{
  "openapi": "3.0.3",
  "info": {
    "title": "Simplybase private management API",
    "version": "0.2.0",
    "description": "Private lab. Existing personal-token scopes intersect current organization/project roles on every request. Developer/read-only currently provide catalog inspection only. Tailscale admission remains separate. Team mutations require a recent browser session; existing PATs gain no team-administration capability."
  },
  "servers": [
    {
      "url": "/platform/api/v1"
    }
  ],
  "components": {
    "securitySchemes": {
      "personalToken": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "sbm_\u2026"
      },
      "browserSession": {
        "type": "apiKey",
        "in": "cookie",
        "name": "__Secure-simplybase-customer"
      }
    }
  },
  "paths": {
    "/me": {
      "get": {
        "summary": "GET /me",
        "security": [
          {
            "personalToken": []
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Owned resources only."
          },
          "401": {
            "description": "Invalid/revoked token or mismatched private identity"
          },
          "403": {
            "description": "Insufficient scope"
          },
          "404": {
            "description": "Unknown or unowned resource"
          },
          "409": {
            "description": "Capacity, generation or idempotency conflict"
          }
        }
      }
    },
    "/organizations": {
      "get": {
        "summary": "GET /organizations",
        "security": [
          {
            "personalToken": []
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Owned resources only."
          },
          "401": {
            "description": "Invalid/revoked token or mismatched private identity"
          },
          "403": {
            "description": "Insufficient scope"
          },
          "404": {
            "description": "Unknown or unowned resource"
          },
          "409": {
            "description": "Capacity, generation or idempotency conflict"
          }
        }
      }
    },
    "/organizations/{id}": {
      "patch": {
        "summary": "PATCH /organizations/{id}",
        "security": [
          {
            "personalToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Owned resources only."
          },
          "401": {
            "description": "Invalid/revoked token or mismatched private identity"
          },
          "403": {
            "description": "Insufficient scope"
          },
          "404": {
            "description": "Unknown or unowned resource"
          },
          "409": {
            "description": "Capacity, generation or idempotency conflict"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  }
                },
                "required": [
                  "name"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/capacity": {
      "get": {
        "summary": "GET /capacity",
        "security": [
          {
            "personalToken": []
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Owned resources only."
          },
          "401": {
            "description": "Invalid/revoked token or mismatched private identity"
          },
          "403": {
            "description": "Insufficient scope"
          },
          "404": {
            "description": "Unknown or unowned resource"
          },
          "409": {
            "description": "Capacity, generation or idempotency conflict"
          }
        }
      }
    },
    "/projects": {
      "get": {
        "summary": "GET /projects",
        "security": [
          {
            "personalToken": []
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Owned resources only."
          },
          "401": {
            "description": "Invalid/revoked token or mismatched private identity"
          },
          "403": {
            "description": "Insufficient scope"
          },
          "404": {
            "description": "Unknown or unowned resource"
          },
          "409": {
            "description": "Capacity, generation or idempotency conflict"
          }
        }
      },
      "post": {
        "summary": "POST /projects",
        "security": [
          {
            "personalToken": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Durably accepted operation; poll its ID."
          },
          "401": {
            "description": "Invalid/revoked token or mismatched private identity"
          },
          "403": {
            "description": "Insufficient scope"
          },
          "404": {
            "description": "Unknown or unowned resource"
          },
          "409": {
            "description": "Capacity, generation or idempotency conflict"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 80
                  },
                  "organization_id": {
                    "type": "string",
                    "format": "uuid"
                  }
                },
                "required": [
                  "name",
                  "organization_id"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/projects/{ref}": {
      "get": {
        "summary": "GET /projects/{ref}",
        "security": [
          {
            "personalToken": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Owned resources only."
          },
          "401": {
            "description": "Invalid/revoked token or mismatched private identity"
          },
          "403": {
            "description": "Insufficient scope"
          },
          "404": {
            "description": "Unknown or unowned resource"
          },
          "409": {
            "description": "Capacity, generation or idempotency conflict"
          }
        }
      }
    },
    "/projects/{ref}/pause": {
      "post": {
        "summary": "POST /projects/{ref}/pause",
        "security": [
          {
            "personalToken": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Durably accepted operation; poll its ID."
          },
          "401": {
            "description": "Invalid/revoked token or mismatched private identity"
          },
          "403": {
            "description": "Insufficient scope"
          },
          "404": {
            "description": "Unknown or unowned resource"
          },
          "409": {
            "description": "Capacity, generation or idempotency conflict"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "generation": {
                    "type": "integer",
                    "minimum": 1
                  }
                },
                "required": [
                  "generation"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/projects/{ref}/resume": {
      "post": {
        "summary": "POST /projects/{ref}/resume",
        "security": [
          {
            "personalToken": []
          }
        ],
        "parameters": [
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Durably accepted operation; poll its ID."
          },
          "401": {
            "description": "Invalid/revoked token or mismatched private identity"
          },
          "403": {
            "description": "Insufficient scope"
          },
          "404": {
            "description": "Unknown or unowned resource"
          },
          "409": {
            "description": "Capacity, generation or idempotency conflict"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "generation": {
                    "type": "integer",
                    "minimum": 1
                  }
                },
                "required": [
                  "generation"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/operations/{id}": {
      "get": {
        "summary": "GET /operations/{id}",
        "security": [
          {
            "personalToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Owned resources only."
          },
          "401": {
            "description": "Invalid/revoked token or mismatched private identity"
          },
          "403": {
            "description": "Insufficient scope"
          },
          "404": {
            "description": "Unknown or unowned resource"
          },
          "409": {
            "description": "Capacity, generation or idempotency conflict"
          }
        }
      }
    },
    "/operations/{id}/retry": {
      "post": {
        "summary": "POST /operations/{id}/retry",
        "security": [
          {
            "personalToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Durably accepted operation; poll its ID."
          },
          "401": {
            "description": "Invalid/revoked token or mismatched private identity"
          },
          "403": {
            "description": "Insufficient scope"
          },
          "404": {
            "description": "Unknown or unowned resource"
          },
          "409": {
            "description": "Capacity, generation or idempotency conflict"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {},
                "required": [],
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/organizations/{id}/team": {
      "get": {
        "summary": "GET /organizations/{id}/team",
        "security": [
          {
            "personalToken": []
          },
          {
            "browserSession": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Current authorized team data or completed control-plane action."
          },
          "401": {
            "description": "Login required; mutations require authentication within 15 minutes."
          },
          "403": {
            "description": "Role, credential kind or CSRF denied."
          },
          "404": {
            "description": "Resource not visible or invitation unavailable."
          },
          "409": {
            "description": "Stale revision, last-owner protection or membership conflict."
          }
        }
      }
    },
    "/organizations/{id}/members/{actor}": {
      "patch": {
        "summary": "PATCH /organizations/{id}/members/{actor}",
        "security": [
          {
            "browserSession": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "actor",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Simplybase-Request",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-CSRF-Token",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Current authorized team data or completed control-plane action."
          },
          "401": {
            "description": "Login required; mutations require authentication within 15 minutes."
          },
          "403": {
            "description": "Role, credential kind or CSRF denied."
          },
          "404": {
            "description": "Resource not visible or invitation unavailable."
          },
          "409": {
            "description": "Stale revision, last-owner protection or membership conflict."
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "role": {
                    "type": "string",
                    "enum": [
                      "owner",
                      "admin",
                      "developer",
                      "read_only",
                      "no_access"
                    ]
                  },
                  "revision": {
                    "type": "integer",
                    "minimum": 1
                  }
                },
                "required": [
                  "role",
                  "revision"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      },
      "delete": {
        "summary": "DELETE /organizations/{id}/members/{actor}",
        "security": [
          {
            "browserSession": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "actor",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Simplybase-Request",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-CSRF-Token",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Current authorized team data or completed control-plane action."
          },
          "401": {
            "description": "Login required; mutations require authentication within 15 minutes."
          },
          "403": {
            "description": "Role, credential kind or CSRF denied."
          },
          "404": {
            "description": "Resource not visible or invitation unavailable."
          },
          "409": {
            "description": "Stale revision, last-owner protection or membership conflict."
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "revision": {
                    "type": "integer",
                    "minimum": 1
                  }
                },
                "required": [
                  "revision"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/organizations/{id}/members/{actor}/projects/{ref}": {
      "patch": {
        "summary": "PATCH /organizations/{id}/members/{actor}/projects/{ref}",
        "security": [
          {
            "browserSession": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "actor",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Simplybase-Request",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-CSRF-Token",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Current authorized team data or completed control-plane action."
          },
          "401": {
            "description": "Login required; mutations require authentication within 15 minutes."
          },
          "403": {
            "description": "Role, credential kind or CSRF denied."
          },
          "404": {
            "description": "Resource not visible or invitation unavailable."
          },
          "409": {
            "description": "Stale revision, last-owner protection or membership conflict."
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "role": {
                    "type": "string",
                    "enum": [
                      "admin",
                      "developer",
                      "read_only"
                    ],
                    "nullable": false
                  },
                  "revision": {
                    "type": "integer",
                    "minimum": 1
                  }
                },
                "required": [
                  "role",
                  "revision"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      },
      "delete": {
        "summary": "DELETE /organizations/{id}/members/{actor}/projects/{ref}",
        "security": [
          {
            "browserSession": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "actor",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ref",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Simplybase-Request",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-CSRF-Token",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Current authorized team data or completed control-plane action."
          },
          "401": {
            "description": "Login required; mutations require authentication within 15 minutes."
          },
          "403": {
            "description": "Role, credential kind or CSRF denied."
          },
          "404": {
            "description": "Resource not visible or invitation unavailable."
          },
          "409": {
            "description": "Stale revision, last-owner protection or membership conflict."
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "revision": {
                    "type": "integer",
                    "minimum": 1
                  }
                },
                "required": [
                  "revision"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/organizations/{id}/invitations": {
      "post": {
        "summary": "POST /organizations/{id}/invitations",
        "security": [
          {
            "browserSession": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Simplybase-Request",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-CSRF-Token",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Current authorized team data or completed control-plane action."
          },
          "401": {
            "description": "Login required; mutations require authentication within 15 minutes."
          },
          "403": {
            "description": "Role, credential kind or CSRF denied."
          },
          "404": {
            "description": "Resource not visible or invitation unavailable."
          },
          "409": {
            "description": "Stale revision, last-owner protection or membership conflict."
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email"
                  },
                  "role": {
                    "type": "string",
                    "enum": [
                      "owner",
                      "admin",
                      "developer",
                      "read_only",
                      "no_access"
                    ]
                  },
                  "ref": {
                    "type": "string",
                    "nullable": true
                  },
                  "project_role": {
                    "type": "string",
                    "enum": [
                      "admin",
                      "developer",
                      "read_only"
                    ],
                    "nullable": true
                  }
                },
                "required": [
                  "email",
                  "role",
                  "ref",
                  "project_role"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/organizations/{id}/invitations/{invitation}": {
      "delete": {
        "summary": "DELETE /organizations/{id}/invitations/{invitation}",
        "security": [
          {
            "browserSession": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "invitation",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Simplybase-Request",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-CSRF-Token",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Current authorized team data or completed control-plane action."
          },
          "401": {
            "description": "Login required; mutations require authentication within 15 minutes."
          },
          "403": {
            "description": "Role, credential kind or CSRF denied."
          },
          "404": {
            "description": "Resource not visible or invitation unavailable."
          },
          "409": {
            "description": "Stale revision, last-owner protection or membership conflict."
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {},
                "required": [],
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/invitations/accept": {
      "post": {
        "summary": "POST /invitations/accept",
        "security": [
          {
            "browserSession": []
          }
        ],
        "parameters": [
          {
            "name": "Origin",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Simplybase-Request",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-CSRF-Token",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Current authorized team data or completed control-plane action."
          },
          "401": {
            "description": "Login required; mutations require authentication within 15 minutes."
          },
          "403": {
            "description": "Role, credential kind or CSRF denied."
          },
          "404": {
            "description": "Resource not visible or invitation unavailable."
          },
          "409": {
            "description": "Stale revision, last-owner protection or membership conflict."
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "code": {
                    "type": "string",
                    "minLength": 43,
                    "maxLength": 43
                  }
                },
                "required": [
                  "code"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      }
    }
  }
}
