{
  "openapi": "3.1.0",
  "info": {
    "title": "Diali public catalog API",
    "version": "1.0.0",
    "summary": "Read-only product catalog: plans, prices, engines, channels, AI models and community skills.",
    "description": "The unauthenticated part of the Diali API. Everything here is a public GET that needs no key,\nno account and no session, and it is the same data the website renders, so prices and\navailability read from it are current by construction.\n\nNot documented here: the rest of the API. Managing assistants, billing, credentials and account\ndata all require a signed-in session and are not part of the public surface.\n\nUnits: prices are integer minor units of `priceCurrency` (US cents, taxes excluded), so 2999 is\n$29.99. Diali AI credit amounts are micro-dollars, so 1000000 is 1 USD.\n\nErrors: every documented failure below returns JSON in this shape:\n`{ \"error\": { \"code\", \"message\", \"details\"? } }`, where `details` is optional structured context. Branch on `code`, which is stable and snake_case; `message` is written for people\nand may be reworded. On these endpoints the codes are `bad_request` (a query parameter was\nrejected, and the message names the accepted values so the call can be corrected and retried)\nand `not_found` (no such resource, so re-read the identifier from its list endpoint rather than\ncomposing one). One exception worth coding for: a gateway-class 5xx is generated by the CDN\nrather than by the API, so it carries no envelope and may well be an HTML document. Branch on\nthe status before the body, and treat any 5xx as transient: retry with backoff instead of\ntrying to parse it. A path that is not documented here answers a plain-text\n`404 page not found` rather than the envelope.\n\nVersioning: the major version is in the path. A breaking change ships as a new prefix, never\nas a change to `v1`. Additive changes land in `v1` at any time (a new field, a new enum\nmember, a new endpoint), so parse defensively: ignore fields you do not recognise, and do\nnot treat an unknown enum value as an error.\n\nDeprecation: a deprecated operation is marked `deprecated: true` here AND signals itself on\nthe wire, so a client that never re-reads this document still finds out. It answers with a\n`Deprecation` header carrying the date the deprecation took effect (RFC 9745) and a `Sunset`\nheader carrying the date it will stop answering (RFC 8594), plus a `Link` header with\n`rel=\"deprecation\"` pointing at what to move to. No response carries these headers yet:\n`listUseCases` is deprecated and marked so here, but still answers without them. When a\nresponse does carry them, that is the notice, and the `Sunset` date is the deadline.\n\nRate limits: responses carry the remaining budget in headers and a 429 carries `Retry-After`.\nRead them and self-throttle rather than discovering the limit by hitting it.",
    "termsOfService": "https://www.diali.ai/terms-of-service",
    "contact": {
      "name": "Diali support",
      "email": "support@diali.ai",
      "url": "https://www.diali.ai/contact"
    }
  },
  "servers": [
    {
      "url": "https://www.diali.ai",
      "description": "Production"
    }
  ],
  "externalDocs": {
    "url": "https://www.diali.ai/llms.txt",
    "description": "Plain-language overview of the product, written for agents."
  },
  "tags": [
    {
      "name": "catalog",
      "description": "Product catalog: what can be bought and what an assistant can be built from."
    },
    {
      "name": "meta",
      "description": "Service metadata."
    }
  ],
  "paths": {
    "/api/v1/catalog/runtimes": {
      "get": {
        "operationId": "listRuntimes",
        "summary": "Assistant engines",
        "description": "List the engines an assistant can run on (OpenClaw, Hermes) with what each is for. Call this to answer which engine suits a described job, or before quoting what an engine can do. The list also carries paperclip, the engine of the Workspace plans, which Diali does not sell on its site; leave it out when describing the assistant engines.",
        "tags": [
          "catalog"
        ],
        "responses": {
          "200": {
            "description": "ok",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Runtime"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/catalog/sizes": {
      "get": {
        "operationId": "listSizes",
        "summary": "Plan tiers and prices",
        "description": "List the plan tiers with current prices for monthly, six-month and annual terms, any running discount, and the AI credits each includes. This is the price source of truth: call it rather than quoting a price from memory. Amounts are integer US cents; aiIncludedMonthlyMicro is micro-dollars. The small, medium and large sizes are sold as Starter, Pro and Max; the pc-* sizes are the Paperclip Workspace ladder, which Diali does not sell on its site, so leave them out when answering what Diali costs.",
        "tags": [
          "catalog"
        ],
        "responses": {
          "200": {
            "description": "ok",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Size"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/catalog/addons": {
      "get": {
        "operationId": "listAddons",
        "summary": "Optional add-ons and prices",
        "description": "List the optional extras that can be added to a plan, with their per-assistant monthly prices in integer US cents. Call this when totalling what a described setup would cost.",
        "tags": [
          "catalog"
        ],
        "responses": {
          "200": {
            "description": "ok",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Addon"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/catalog/providers": {
      "get": {
        "operationId": "listProviders",
        "summary": "Bring-your-own-key AI providers and their models",
        "description": "List the AI providers a customer can connect their own API key to, and the models each exposes. Call this to answer whether a particular provider or model is supported when bringing your own key.",
        "tags": [
          "catalog"
        ],
        "responses": {
          "200": {
            "description": "ok",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Provider"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/catalog/channels": {
      "get": {
        "operationId": "listChannels",
        "summary": "Messaging channels an assistant can be deployed into",
        "description": "List the messaging channels an assistant can be deployed into, with which are live and which are coming soon. Call this to answer whether Diali supports a given app before saying yes or no.",
        "tags": [
          "catalog"
        ],
        "responses": {
          "200": {
            "description": "ok",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Channel"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/catalog/use-cases": {
      "get": {
        "operationId": "listUseCases",
        "summary": "Starting-point use cases (deprecated)",
        "description": "Deprecated: superseded by the skill catalog (browseSkills) and the curated skill packs (listSkillPacks); do not build new work on it. Lists the prepared use cases the old setup wizard started an assistant from.",
        "tags": [
          "catalog"
        ],
        "deprecated": true,
        "responses": {
          "200": {
            "description": "ok",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/UseCase"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/catalog/personalities": {
      "get": {
        "operationId": "listPersonalities",
        "summary": "Personality presets",
        "description": "List the personality presets an assistant can be given. Call this when asked how an assistant can be made to sound.",
        "tags": [
          "catalog"
        ],
        "responses": {
          "200": {
            "description": "ok",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Personality"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/catalog/skill-publishers": {
      "get": {
        "operationId": "listSkillPublishers",
        "summary": "Skill publishers",
        "description": "List the publishers whose skills appear in the catalog. Call this to resolve a publisher handle before filtering the skill browse endpoint by owner.",
        "tags": [
          "catalog"
        ],
        "responses": {
          "200": {
            "description": "ok",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SkillPublisher"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/catalog/skill-packs": {
      "get": {
        "operationId": "listSkillPacks",
        "summary": "Curated skill packs",
        "description": "List the curated bundles of skills that can be installed together. Call this when recommending a starting set of capabilities rather than individual skills.",
        "tags": [
          "catalog"
        ],
        "responses": {
          "200": {
            "description": "ok",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/SkillPack"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/catalog/company-templates": {
      "get": {
        "operationId": "listCompanyTemplates",
        "summary": "Ready-made multi-assistant setups",
        "description": "List the ready-made setups that create several assistants at once, with how many they create and the plan size each is tuned for. Call this when the question is about running a team of assistants rather than one.",
        "tags": [
          "catalog"
        ],
        "responses": {
          "200": {
            "description": "ok",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CompanyTemplate"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/catalog/managed-models": {
      "get": {
        "operationId": "listManagedModels",
        "summary": "Models billed in Diali AI credits, with their credit prices",
        "description": "List the AI models Diali hosts and bills in Diali AI credits, with the credit price of each. Call this to answer what a given model costs to run, or which models are available without bringing your own key.",
        "tags": [
          "catalog"
        ],
        "responses": {
          "200": {
            "description": "ok",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ManagedModel"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/catalog/skills": {
      "get": {
        "operationId": "browseSkills",
        "summary": "Browse the community skill catalog",
        "description": "Cursor-paginated. Pass the `next_cursor` from a response back as `cursor` to continue; a null `next_cursor` means the last page.",
        "tags": [
          "catalog"
        ],
        "parameters": [
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "Browse tab.",
            "schema": {
              "type": "string",
              "enum": [
                "trending",
                "recommended",
                "downloads",
                "stars",
                "new",
                "updated"
              ],
              "default": "trending"
            }
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "description": "Browse facet. An unknown value is a 400.",
            "schema": {
              "type": "string",
              "enum": [
                "integrations",
                "automation",
                "research",
                "development",
                "productivity",
                "communication",
                "creative",
                "knowledge",
                "agents",
                "operations",
                "security",
                "finance",
                "lifestyle",
                "other"
              ]
            }
          },
          {
            "name": "runtime",
            "in": "query",
            "required": false,
            "description": "Hide skills that cannot run on this runtime.",
            "schema": {
              "type": "string",
              "enum": [
                "openclaw",
                "hermes"
              ]
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Free text over name, summary and topics, plus a slug substring match. Always spans the whole registry.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "owner",
            "in": "query",
            "required": false,
            "description": "Publisher handle. Always spans the whole registry.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "scope",
            "in": "query",
            "required": false,
            "description": "shelf = curated rows plus registry rows with a real usage signal; all = the entire registry.",
            "schema": {
              "type": "string",
              "enum": [
                "shelf",
                "all"
              ],
              "default": "shelf"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Opaque cursor from a previous response.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Rows per page.",
            "schema": {
              "type": "integer",
              "default": 20,
              "maximum": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "ok",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Skill"
                      }
                    },
                    "next_cursor": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Cursor for the next page, null on the last page."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "A query parameter was rejected: an unknown `category`, `sort` or `scope`, or a malformed `cursor`. The message names the accepted values, so it can be retried without guessing. Note that `limit` above the maximum is clamped rather than rejected, and an unknown `runtime` filters to an empty list.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/catalog/skills/{slug}": {
      "get": {
        "operationId": "getSkill",
        "summary": "One catalog skill, with its security review",
        "description": "Fetch one community skill by slug, including the security review shown before install: a verdict, a plain-language summary of what the skill does, and the date it was checked. Call this before telling anyone a skill is safe.",
        "tags": [
          "catalog"
        ],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Skill slug from the browse endpoint.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "ok",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SkillDetail"
                }
              }
            }
          },
          "404": {
            "description": "No skill with that slug. Slugs come from the browse endpoint; they are publisher-scoped, so re-read one from `data[].slug` rather than composing it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/healthz": {
      "get": {
        "operationId": "health",
        "summary": "Service health",
        "description": "Report whether the API is serving traffic. Call this to distinguish an outage from a rejected request before retrying.",
        "tags": [
          "meta"
        ],
        "responses": {
          "200": {
            "description": "The API is serving traffic."
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Error": {
        "type": "object",
        "description": "The error envelope every failing endpoint returns. Branch on `error.code`, which is stable; `error.message` is written for people and may be reworded.",
        "properties": {
          "error": {
            "type": "object",
            "description": "The failure.",
            "properties": {
              "code": {
                "type": "string",
                "description": "Stable machine code in snake_case. On the public endpoints: bad_request (a query parameter was rejected) or not_found (no such resource)."
              },
              "message": {
                "type": "string",
                "description": "Plain-language, client-safe explanation. Public endpoints name the accepted values, e.g. \"Unknown sort. Use trending, recommended, downloads, stars, new or updated.\""
              },
              "details": {
                "type": "object",
                "additionalProperties": true,
                "description": "Optional structured context, when an endpoint has more to say than the message."
              }
            }
          }
        }
      },
      "Runtime": {
        "type": "object",
        "description": "An assistant engine. One engine is chosen per assistant.",
        "properties": {
          "slug": {
            "type": "string",
            "description": "Stable identifier, e.g. openclaw or hermes."
          },
          "name": {
            "type": "string",
            "description": "Display name."
          },
          "description": {
            "type": "string",
            "description": "One-line summary of what the engine is for."
          },
          "orderable": {
            "type": "boolean",
            "description": "False when the engine exists but cannot currently be subscribed to."
          }
        }
      },
      "Size": {
        "type": "object",
        "description": "A plan tier. The pricing page renders from this endpoint, so it is the price source of truth.",
        "properties": {
          "slug": {
            "type": "string",
            "description": "Catalog identifier: small, medium or large (sold as Starter, Pro and Max)."
          },
          "name": {
            "type": "string",
            "description": "Catalog name."
          },
          "description": {
            "type": "string",
            "description": "Who the tier suits."
          },
          "priceAmount": {
            "type": "integer",
            "description": "Monthly price. Integer minor units of priceCurrency (US cents), taxes excluded."
          },
          "priceAmountSixMonth": {
            "type": "integer",
            "description": "Total charged for a six-month term. Integer minor units of priceCurrency (US cents), taxes excluded."
          },
          "priceAmountAnnual": {
            "type": "integer",
            "description": "Total charged for an annual term. Integer minor units of priceCurrency (US cents), taxes excluded."
          },
          "priceCurrency": {
            "type": "string",
            "description": "ISO 4217 code, e.g. USD."
          },
          "compareAtAmount": {
            "type": "integer",
            "description": "List price before any active offer, monthly. Integer minor units of priceCurrency (US cents), taxes excluded."
          },
          "compareAtAmountSixMonth": {
            "type": "integer",
            "description": "List price before any active offer, six-month. Integer minor units of priceCurrency (US cents), taxes excluded."
          },
          "compareAtAmountAnnual": {
            "type": "integer",
            "description": "List price before any active offer, annual. Integer minor units of priceCurrency (US cents), taxes excluded."
          },
          "discountPercent": {
            "type": "integer",
            "description": "Percentage off the compare-at price, 0 when no offer is running."
          },
          "discountLabel": {
            "type": "string",
            "description": "Human-readable offer label, empty when no offer is running."
          },
          "aiIncludedMonthlyMicro": {
            "type": "integer",
            "description": "Included Diali AI credits per month, in micro-dollars (1000000 = 1 USD)."
          },
          "supportedRuntimeSlugs": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Runtime slugs this tier can run."
          }
        }
      },
      "Addon": {
        "type": "object",
        "description": "An optional extra, priced per assistant per month.",
        "properties": {
          "slug": {
            "type": "string",
            "description": "Stable identifier."
          },
          "name": {
            "type": "string",
            "description": "Display name."
          },
          "description": {
            "type": "string",
            "description": "What the add-on does."
          },
          "priceAmount": {
            "type": "integer",
            "description": "Monthly price. Integer minor units of priceCurrency (US cents), taxes excluded."
          },
          "priceAmountSixMonth": {
            "type": "integer",
            "description": "Six-month total. Integer minor units of priceCurrency (US cents), taxes excluded."
          },
          "priceAmountAnnual": {
            "type": "integer",
            "description": "Annual total. Integer minor units of priceCurrency (US cents), taxes excluded."
          },
          "priceCurrency": {
            "type": "string",
            "description": "ISO 4217 code."
          },
          "billableUnit": {
            "type": "string",
            "description": "What the price is charged per, e.g. per_agent_month or per_gb_month."
          },
          "supportedRuntimes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Runtime slugs the add-on applies to."
          },
          "compatibleSizes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Size slugs the add-on can be bought on; empty means all."
          },
          "hasDashboard": {
            "type": "boolean",
            "description": "True when the add-on adds a browser dashboard."
          },
          "selfServe": {
            "type": "boolean",
            "description": "True when it can be added without contacting support."
          },
          "dashboardAuth": {
            "type": "string",
            "description": "How the add-on’s dashboard authenticates, when it has one, e.g. credentials."
          }
        }
      },
      "Provider": {
        "type": "object",
        "description": "An AI provider you can connect with your own key, and the models it exposes.",
        "properties": {
          "slug": {
            "type": "string",
            "description": "Provider identifier, e.g. anthropic."
          },
          "name": {
            "type": "string",
            "description": "Display name."
          },
          "kind": {
            "type": "string",
            "description": "Provider family, e.g. llm."
          },
          "keyPrefix": {
            "type": "string",
            "description": "Expected API-key prefix, used to validate a pasted key."
          },
          "consoleUrl": {
            "type": "string",
            "description": "Where a customer creates a key with this provider."
          },
          "byoServerUrl": {
            "type": "boolean",
            "description": "True when a self-hosted base URL may be supplied (e.g. Ollama)."
          },
          "supportedRuntimes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Runtime slugs that can use this provider."
          },
          "models": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProviderModel"
            },
            "description": "Models selectable on this provider."
          },
          "capabilities": {
            "type": "object",
            "additionalProperties": true,
            "description": "Provider-reported capability map, e.g. which runtimes can use it for tts or stt."
          }
        }
      },
      "ProviderModel": {
        "type": "object",
        "description": "One model on a bring-your-own-key provider. Prices are the provider’s own; Diali does not bill them.",
        "properties": {
          "slug": {
            "type": "string",
            "description": "Model identifier as the provider names it."
          },
          "name": {
            "type": "string",
            "description": "Display name."
          },
          "inputPricePer1M": {
            "type": "integer",
            "description": "Provider price per 1M input tokens. Integer minor units of priceCurrency (US cents), taxes excluded."
          },
          "outputPricePer1M": {
            "type": "integer",
            "description": "Provider price per 1M output tokens. Integer minor units of priceCurrency (US cents), taxes excluded."
          },
          "priceCurrency": {
            "type": "string",
            "description": "ISO 4217 code."
          },
          "pricing": {
            "type": "object",
            "additionalProperties": true,
            "description": "Provider-reported pricing detail (cache tiers and similar)."
          },
          "contextWindow": {
            "type": "integer",
            "description": "Maximum context in tokens."
          },
          "maxOutputTokens": {
            "type": "integer",
            "description": "Maximum tokens the model will emit in one response."
          },
          "isReasoning": {
            "type": "boolean",
            "description": "True when the model supports extended thinking."
          },
          "speed": {
            "type": "object",
            "additionalProperties": true,
            "description": "Provider-reported latency/throughput detail."
          },
          "supportsVision": {
            "type": "boolean",
            "description": "True when the model accepts images."
          },
          "subagentSuitable": {
            "type": "boolean",
            "description": "True when the model is a sensible choice for delegated subagent work."
          },
          "supportedRuntimes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Runtime slugs that can run this model."
          }
        }
      },
      "ManagedModel": {
        "type": "object",
        "description": "A model billed in Diali AI credits, so no provider account is needed. Prices are micro-dollars per 1M tokens.",
        "properties": {
          "provider": {
            "type": "string",
            "description": "Upstream provider slug."
          },
          "providerName": {
            "type": "string",
            "description": "Upstream provider display name."
          },
          "slug": {
            "type": "string",
            "description": "Model identifier."
          },
          "name": {
            "type": "string",
            "description": "Display name."
          },
          "inputMicroPer1M": {
            "type": "integer",
            "description": "Credit cost per 1M input tokens, in micro-dollars."
          },
          "outputMicroPer1M": {
            "type": "integer",
            "description": "Credit cost per 1M output tokens, in micro-dollars."
          },
          "cacheReadMicroPer1M": {
            "type": "integer",
            "description": "Credit cost per 1M cached input tokens read, in micro-dollars."
          },
          "cacheWriteMicroPer1M": {
            "type": "integer",
            "description": "Credit cost per 1M tokens written to cache, in micro-dollars."
          },
          "contextWindow": {
            "type": "integer",
            "description": "Maximum context in tokens."
          },
          "maxOutputTokens": {
            "type": "integer",
            "description": "Maximum tokens emitted in one response."
          },
          "reasoning": {
            "type": "boolean",
            "description": "True when the model supports extended thinking."
          },
          "vision": {
            "type": "boolean",
            "description": "True when the model accepts images."
          },
          "speedTier": {
            "type": "string",
            "description": "Relative speed band, e.g. fast or standard."
          },
          "deprecated": {
            "type": "boolean",
            "description": "True when the model is being retired and should not be chosen for new work."
          },
          "supportedRuntimes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Runtime slugs that can run this model; empty means all."
          }
        }
      },
      "Channel": {
        "type": "object",
        "description": "A messaging channel an assistant can be deployed into.",
        "properties": {
          "slug": {
            "type": "string",
            "description": "Channel identifier, e.g. telegram."
          },
          "name": {
            "type": "string",
            "description": "Display name."
          },
          "description": {
            "type": "string",
            "description": "What connecting this channel gives you."
          },
          "availability": {
            "type": "string",
            "description": "Whether the channel is live or announced, e.g. available or coming_soon."
          },
          "credentialsSchema": {
            "type": "object",
            "additionalProperties": true,
            "description": "Form definition for what the customer must supply, as { fields: [{ key, type, label, required, help }] }."
          },
          "supportedRuntimes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Runtime slugs that can serve this channel."
          },
          "requiredAddon": {
            "type": "string",
            "description": "Add-on slug that must be bought before this channel can be used, when one is required."
          }
        }
      },
      "UseCase": {
        "type": "object",
        "description": "A starting-point purpose offered during assistant setup.",
        "properties": {
          "slug": {
            "type": "string",
            "description": "Identifier."
          },
          "name": {
            "type": "string",
            "description": "Display name."
          },
          "description": {
            "type": "string",
            "description": "What the assistant would do."
          }
        }
      },
      "Personality": {
        "type": "object",
        "description": "A personality preset offered during assistant setup.",
        "properties": {
          "slug": {
            "type": "string",
            "description": "Identifier."
          },
          "name": {
            "type": "string",
            "description": "Display name."
          },
          "description": {
            "type": "string",
            "description": "How the assistant behaves."
          },
          "sampleLine": {
            "type": "string",
            "description": "An example line in this persona’s voice."
          },
          "iconEmoji": {
            "type": "string",
            "description": "Emoji used on the preset card."
          },
          "supportedRuntimes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Runtime slugs offering this preset."
          }
        }
      },
      "Skill": {
        "type": "object",
        "description": "A community skill from the catalog. Every entry carries a security review before install.",
        "properties": {
          "slug": {
            "type": "string",
            "description": "Catalog identifier, publisher-scoped."
          },
          "name": {
            "type": "string",
            "description": "Display name."
          },
          "skillName": {
            "type": "string",
            "description": "Name the skill registers itself under at runtime."
          },
          "summary": {
            "type": "string",
            "description": "One-line description."
          },
          "category": {
            "type": "string",
            "description": "Browse facet, e.g. integrations or research."
          },
          "supportedRuntimes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Runtime slugs the skill can run on."
          },
          "needsSetup": {
            "type": "boolean",
            "description": "True when the skill needs credentials or configuration before use."
          },
          "trust": {
            "type": "string",
            "description": "Outcome of the security review shown before install."
          },
          "sourceUrl": {
            "type": "string",
            "description": "Where the skill’s source can be read."
          },
          "source": {
            "type": "string",
            "description": "Registry the entry was mirrored from."
          },
          "topics": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Free-form tags."
          },
          "stars": {
            "type": "integer",
            "description": "Stars on the upstream registry."
          },
          "downloads": {
            "type": "integer",
            "description": "Downloads reported by the upstream registry."
          },
          "installs": {
            "type": "integer",
            "description": "Installs on Diali."
          },
          "version": {
            "type": "string",
            "description": "Catalogued version."
          },
          "status": {
            "type": "string",
            "description": "Catalog state, e.g. active, hidden, blocked or archived."
          },
          "installable": {
            "type": "boolean",
            "description": "False for tombstoned entries (blocked or archived) that resolve only so an existing install stays readable."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the entry first appeared."
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the entry was last refreshed."
          },
          "publisher": {
            "$ref": "#/components/schemas/SkillPublisherRef"
          },
          "security": {
            "$ref": "#/components/schemas/SkillSecurity"
          }
        }
      },
      "SkillDetail": {
        "type": "object",
        "description": "One catalog skill with its review detail: the read-before-install surface.",
        "properties": {
          "slug": {
            "type": "string",
            "description": "Catalog identifier."
          },
          "name": {
            "type": "string",
            "description": "Display name."
          },
          "skillName": {
            "type": "string",
            "description": "Runtime name."
          },
          "summary": {
            "type": "string",
            "description": "One-line description."
          },
          "category": {
            "type": "string",
            "description": "Browse facet."
          },
          "supportedRuntimes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Runtime slugs the skill can run on."
          },
          "needsSetup": {
            "type": "boolean",
            "description": "True when configuration is required before use."
          },
          "trust": {
            "type": "string",
            "description": "Security-review verdict."
          },
          "sourceUrl": {
            "type": "string",
            "description": "Where the source can be read."
          },
          "source": {
            "type": "string",
            "description": "Upstream registry."
          },
          "topics": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Free-form tags."
          },
          "stars": {
            "type": "integer",
            "description": "Upstream stars."
          },
          "downloads": {
            "type": "integer",
            "description": "Upstream downloads."
          },
          "installs": {
            "type": "integer",
            "description": "Installs on Diali."
          },
          "license": {
            "type": "string",
            "description": "SPDX licence identifier where the upstream declares one."
          },
          "version": {
            "type": "string",
            "description": "Catalogued version."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the entry first appeared."
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the entry was last refreshed."
          },
          "status": {
            "type": "string",
            "description": "Catalog state, e.g. active, hidden, blocked or archived."
          },
          "installable": {
            "type": "boolean",
            "description": "False for tombstoned entries that resolve only so an existing install stays readable."
          },
          "publisher": {
            "$ref": "#/components/schemas/SkillPublisherRef"
          },
          "security": {
            "$ref": "#/components/schemas/SkillSecurity"
          }
        }
      },
      "SkillPublisherRef": {
        "type": "object",
        "description": "The publisher as embedded on a skill. Browse rows carry the handle and the badges; the detail endpoint adds the display name and avatar.",
        "properties": {
          "handle": {
            "type": "string",
            "description": "Publisher handle, usable as the owner filter on /api/v1/catalog/skills."
          },
          "displayName": {
            "type": "string",
            "description": "Display name. Present on the detail endpoint."
          },
          "avatarUrl": {
            "type": "string",
            "description": "Avatar image URL. Present on the detail endpoint."
          },
          "verified": {
            "type": "boolean",
            "description": "True when the publisher identity has been verified."
          },
          "official": {
            "type": "boolean",
            "description": "True for first-party publishers."
          }
        }
      },
      "SkillSecurity": {
        "type": "object",
        "description": "The security review shown before install. Every catalog entry carries one.",
        "properties": {
          "verdict": {
            "type": "string",
            "description": "Review outcome, e.g. clean."
          },
          "summary": {
            "type": "string",
            "description": "Plain-language account of what the skill does and what it can reach."
          },
          "checkedAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the review was performed."
          },
          "auditUrl": {
            "type": "string",
            "description": "Link to the full audit, where one is published."
          }
        }
      },
      "SkillPublisher": {
        "type": "object",
        "description": "An author who publishes skills to the catalog.",
        "properties": {
          "handle": {
            "type": "string",
            "description": "Publisher handle, used as the owner filter on /api/v1/catalog/skills."
          },
          "displayName": {
            "type": "string",
            "description": "Display name."
          },
          "avatarUrl": {
            "type": "string",
            "description": "Avatar image URL."
          },
          "verified": {
            "type": "boolean",
            "description": "True when the publisher identity has been verified."
          },
          "official": {
            "type": "boolean",
            "description": "True for first-party publishers."
          },
          "published": {
            "type": "integer",
            "description": "Number of skills published."
          },
          "downloads": {
            "type": "integer",
            "description": "Total downloads across their skills."
          }
        }
      },
      "SkillPack": {
        "type": "object",
        "description": "A curated bundle of skills installable together.",
        "properties": {
          "slug": {
            "type": "string",
            "description": "Identifier."
          },
          "name": {
            "type": "string",
            "description": "Display name."
          },
          "description": {
            "type": "string",
            "description": "What the pack equips an assistant to do."
          },
          "iconEmoji": {
            "type": "string",
            "description": "Emoji used on the pack card."
          },
          "supportedRuntimes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Runtime slugs the pack targets."
          },
          "skills": {
            "type": "array",
            "description": "The skills in the pack.",
            "items": {
              "type": "object",
              "properties": {
                "slug": {
                  "type": "string",
                  "description": "Skill slug."
                },
                "name": {
                  "type": "string",
                  "description": "Skill name."
                },
                "iconEmoji": {
                  "type": "string",
                  "description": "Skill emoji."
                }
              }
            }
          }
        }
      },
      "CompanyTemplate": {
        "type": "object",
        "description": "A ready-made multi-assistant setup that can be provisioned as a unit.",
        "properties": {
          "slug": {
            "type": "string",
            "description": "Identifier."
          },
          "name": {
            "type": "string",
            "description": "Display name."
          },
          "description": {
            "type": "string",
            "description": "What the template sets up."
          },
          "agentsCount": {
            "type": "integer",
            "description": "How many assistants the template creates."
          },
          "skillsCount": {
            "type": "integer",
            "description": "How many skills it installs across them."
          },
          "orgChartUrl": {
            "type": "string",
            "description": "Diagram of how the assistants relate."
          },
          "sourceRepo": {
            "type": "string",
            "description": "Where the template is maintained."
          },
          "license": {
            "type": "string",
            "description": "SPDX licence identifier."
          },
          "recommendedSizeSlug": {
            "type": "string",
            "description": "Size slug the template is tuned for."
          },
          "minSizeSlug": {
            "type": "string",
            "description": "Smallest size slug the template will run on."
          }
        }
      }
    }
  }
}