Topolo Docs Topolo Platform
Open workspace

Create brand kit

Create an active Brand kit container in the selected workspace.

Outcome

Create an active Brand kit container in the selected workspace.

Before you start

  • Verify whoami and the pinned credential context, then inspect the exact discovered action before preparing input.
  • Discover a granted Brand workspace. Pass its resourceType/workspace identifier separately from input; a copied fixture identifier grants no access.
  • The declared permission is brand:write. The active credential, application scope, resource binding and runtime authority must all authorize the request.
  • Review the exact mutation and recovery, including destructive scope, and execute only after the intended effect is authorized.

Discover the target

topolo whoami --json
topolo actions get app_topolo_brand.brand_kits.create --detail --json
topolo resources topolo-brand --json
topolo workspaces list topolo-brand --json

Request

POST /api/brand-kits

Resource context is the selected Brand workspace. CLI/SDK action input includes path identifiers; direct HTTP JSON bodies exclude path parameters. Read the reviewed plan for the exact request.

Input fields

FieldRequiredMeaning
nameYesHuman-readable kit or asset name. Kit metadata changes do not modify an immutable published snapshot.
slugYesAt least two characters, using lowercase letters, digits and single separating hyphens.
descriptionConditional/optionalKit description, at most 500 characters. An omitted creation description becomes an empty string.

Exact published input schema:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "description": "Human-readable kit or asset name. Kit metadata changes do not modify an immutable published snapshot."
    },
    "slug": {
      "type": "string",
      "minLength": 2,
      "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
      "description": "At least two characters, using lowercase letters, digits and single separating hyphens."
    },
    "description": {
      "type": "string",
      "maxLength": 500,
      "description": "Kit description, at most 500 characters. An omitted creation description becomes an empty string."
    }
  },
  "required": [
    "name",
    "slug"
  ],
  "additionalProperties": false
}

Effects

Creates kit metadata and an audit row; it creates no version, binding or asset bytes.

Interpret the response

brandKit contains the generated identifier, active status and currentVersionId:null. Omitted description becomes empty. The kit does not resolve until it has a published version.

Response identifier contract:

{
  "kind": "brand_kit",
  "identifierSource": "response",
  "idPath": "$.brandKit.id"
}

Worked examples

These complete synthetic responses were captured from the local worker over canonical SQL migrations. Auth and R2 dependencies are simulated; notification delivery is not exercised. Set BRAND_WORKSPACE_ID from granted workspace discovery. Save reviewed input as payload.json, validate and inspect the unchanged plan. The final mutation command and MCP confirm flag assume the intended effect has already been authorized.

Minimal example

Input · payload.json:

{
  "name": "Fixture identity",
  "slug": "fixture-minimal"
}

CLI:

topolo actions validate app_topolo_brand.brand_kits.create --data @payload.json --json
topolo actions plan app_topolo_brand.brand_kits.create --resource-type workspace --resource-id "$BRAND_WORKSPACE_ID" --data @payload.json --json
topolo actions call app_topolo_brand.brand_kits.create --resource-type workspace --resource-id "$BRAND_WORKSPACE_ID" --data @payload.json --confirm --json

MCP tool and arguments:

{
  "tool": "topolo_call_action",
  "arguments": {
    "actionId": "app_topolo_brand.brand_kits.create",
    "input": {
      "name": "Fixture identity",
      "slug": "fixture-minimal"
    },
    "resourceType": "workspace",
    "resourceId": "<identifier returned by resource discovery>",
    "confirm": true
  }
}

Captured local response · HTTP 201:

{
  "brandKit": {
    "id": "brand_c794be50-0306-4933-8de8-5609340bed9e",
    "organizationId": "org_documentation_fixture",
    "name": "Fixture identity",
    "slug": "fixture-minimal",
    "description": "",
    "status": "active",
    "createdAt": "2026-10-03T11:23:59.056Z",
    "updatedAt": "2026-10-03T11:23:59.056Z",
    "currentVersionId": null
  }
}

brandKit contains the generated identifier, active status and currentVersionId:null. Omitted description becomes empty. The kit does not resolve until it has a published version.

Workflow example

Input · payload.json:

{
  "name": "Fixture identity",
  "slug": "fixture-workflow",
  "description": "A governed example identity"
}

CLI:

topolo actions validate app_topolo_brand.brand_kits.create --data @payload.json --json
topolo actions plan app_topolo_brand.brand_kits.create --resource-type workspace --resource-id "$BRAND_WORKSPACE_ID" --data @payload.json --json
topolo actions call app_topolo_brand.brand_kits.create --resource-type workspace --resource-id "$BRAND_WORKSPACE_ID" --data @payload.json --confirm --json

MCP tool and arguments:

{
  "tool": "topolo_call_action",
  "arguments": {
    "actionId": "app_topolo_brand.brand_kits.create",
    "input": {
      "name": "Fixture identity",
      "slug": "fixture-workflow",
      "description": "A governed example identity"
    },
    "resourceType": "workspace",
    "resourceId": "<identifier returned by resource discovery>",
    "confirm": true
  }
}

Captured local response · HTTP 201:

{
  "brandKit": {
    "id": "brand_55886012-13a4-4e95-ad31-3fe2b52cdf20",
    "organizationId": "org_documentation_fixture",
    "name": "Fixture identity",
    "slug": "fixture-workflow",
    "description": "A governed example identity",
    "status": "active",
    "createdAt": "2026-10-03T11:23:59.104Z",
    "updatedAt": "2026-10-03T11:23:59.104Z",
    "currentVersionId": null
  }
}

brandKit contains the generated identifier, active status and currentVersionId:null. Omitted description becomes empty. The kit does not resolve until it has a published version.

Verify the result

Read the returned kit identifier and confirm its name, slug and description before creating a draft.

Errors and recovery

refused · HTTP 400

{
  "input": {
    "name": "",
    "slug": "invalid slug"
  },
  "response": {
    "error": "invalid_input",
    "details": [
      {
        "path": [
          "name"
        ],
        "code": "too_small"
      },
      {
        "path": [
          "slug"
        ],
        "code": "invalid_format"
      }
    ]
  }
}

permission denied · HTTP 403

{
  "input": {
    "name": "Refused fixture",
    "slug": "refused-fixture"
  },
  "response": {
    "error": "permission_denied",
    "permission": "brand:write"
  }
}
  • auth_error (HTTP 401): CLI/SDK authentication classification when Auth returns a non-code message: restore the authorized credential, then verify whoami and context. Preserve the exact service message.

  • permission_denied (HTTP 403): Use the exact permission and granted resource required by the reviewed action; organization membership alone is insufficient.

  • workspace_required (HTTP 400): Discover and select a granted Brand workspace before preparing the request.

  • brand_storage_unavailable (HTTP 503): The Brand storage bindings are unavailable. Preserve the request identifier and report the service fault; do not retry an unverified mutation.

  • invalid_input (HTTP 400): Correct the reported fields, validate the complete payload and review the resulting plan before retrying.

Recovery boundary

An authorized brand_kits.delete can remove a never-published, unbound kit and its data. It is permanent, so preserve needed work before deletion.

  • app_topolo_brand.brand_kit_versions.create: Create a draft Brand version from a complete typed snapshot.

Evidence

Four real local SQLite stores use all canonical migrations; Auth identity/grants and archival plus R2 object storage are explicitly simulated. Notifications are disabled in fixtures. No notification delivery, live mutation, gateway credential parity or deployed environment proof is claimed. Fixture identifiers and timestamps are synthetic and must be replaced by exact authorized resource discovery.