Manifest reference
A manifest is the JSON document that defines a Kit. It is a consent document: everything a Kit may do in a workspace is declared here, and the admin who installs the Kit sees it.
JSON Schema: /schemas/kit-manifest/v1.json (draft 2020-12). Its canonical id
is https://ketvia.com/schemas/kit-manifest/v1.json. Point your editor at it for completion and validation. Ketvia
also runs checks that a JSON Schema cannot express (listed below), so a manifest that passes the schema can still be
rejected with a precise message.
General rules
Section titled “General rules”schemaVersionis1. Unknown keys are rejected at every level.- Localized strings are objects such as
{ "en": "Acme CI", "tr": "Acme CI" }.enis required;tris optional and falls back toen. Strings are trimmed and must not be empty. - URLs must be
https, without credentials (user:pass@) or a fragment (#…), at most 2000 characters. - The whole manifest is at most 64 KB.
Example
Section titled “Example”{ "schemaVersion": 1, "slug": "acme-ci-notify", "version": "0.1.0", "displayName": { "en": "Acme CI" }, "description": { "en": "Posts build results to a channel." }, "developer": { "name": "Acme Inc.", "url": "https://acme.dev", "supportEmail": "[email protected]" }, "privacyPolicyUrl": "https://acme.dev/privacy", "bot": { "displayName": { "en": "Acme CI" }, "scopes": ["incoming-webhook"] }, "incomingWebhooks": { "maxPerInstallation": 5 }, "distribution": "private"}Fields
Section titled “Fields”| Field | Type | Required | Rules |
|---|---|---|---|
schemaVersion |
1 |
Yes | Always 1. |
slug |
string | Yes | ^[a-z][a-z0-9-]{1,39}$: 2 to 40 characters, lowercase letters, digits and hyphens, starting with a letter. Global across Ketvia; some slugs are reserved. Never changes. |
version |
string | Yes | major.minor.patch, digits only, no leading zeros, no pre-release suffix (for example 1.4.0). |
displayName |
localized, ≤ 60 | Yes | The Kit’s name. |
description |
localized, ≤ 500 | Yes | What the Kit does, shown at install. |
developer.name |
string, ≤ 80 | Yes | Who publishes the Kit. |
developer.url |
URL | Yes | The developer’s website. |
developer.supportEmail |
email, ≤ 254 | Yes | Where workspace admins get help. |
privacyPolicyUrl |
URL | Yes | The Kit’s privacy policy. |
icon |
URL | No | The Kit’s icon. |
categories |
string[] ≤ 5 | No | Each ^[a-z][a-z0-9-]{1,30}$. Default []. |
locales |
"en" | "tr", 1–2 |
No | Languages the Kit supports. Default ["en"]. Every listed locale other than en needs a displayName in that language. |
bot.displayName |
localized, ≤ 60 | Yes | The Kit bot’s name, shown as the author of its messages. |
bot.scopes |
scope[] | No | Bot scopes. Default []. See Scopes. |
userScopes |
scope[] | No | Scopes a member can grant to a user token. Default []. |
incomingWebhooks |
object | No | { "maxPerInstallation": 1–20 }. Requires the incoming-webhook bot scope. |
oauth.redirectUrls |
URL[] 1–10 | No | Where Ketvia may send the member back in the kit.access flow. The redirect_uri of each request must equal one of them. |
distribution |
string | Yes | private, unlisted or directory. Only private is accepted in this phase. |
requestedModelDataPolicy |
"none" | "answer" |
No | Default none. Must be none in this phase. See Model data policy. |
tools |
object | No | Assistant tools (MCP). Later phase: rejected for private Kits now. See Tools and approvals. |
failureCodes |
object | No | Maps a tool’s machine error codes to Ketvia failure codes. Only meaningful with tools. |
events |
object | No | { url, subscribe[] }. Later phase: rejected for private Kits now. See Events. |
interactivity |
object | No | { url }. Later phase: rejected for private Kits now. See Interactivity. |
commands |
object[] | No | Slash commands. Later phase: rejected for private Kits now. See Commands. |
externalAuth |
object | No | OAuth that Ketvia performs towards the Kit’s own service. Later phase: rejected for private Kits now. |
Cross-field checks
Section titled “Cross-field checks”Beyond the JSON Schema, Ketvia checks:
incomingWebhooksneedsincoming-webhookinbot.scopes.commandsneeds thecommandsbot scope; each event subscription needs the matching read scope.- Each locale in
localesother thanenhas adisplayNamein that language. - Private Kits in this phase:
distributionisprivate,requestedModelDataPolicyisnone, and there is notools,events,interactivity,commandsorexternalAuthsection and nocommandsorassistant:toolsbot scope.
Ketvia answers the first problem it finds with the field path, for example
Invalid manifest: bot.scopes.0: ….
Versions and updates
Section titled “Versions and updates”To update a private Kit, upload a manifest with the same slug and a higher version through Create a private
Kit. The Kit and the workspace’s installation move to the new version at once.
- A version equal to or lower than the installed one is rejected.
- Uploading an existing version with different content is rejected: versions are immutable.
- If the new version requests fewer scopes, existing tokens lose the removed scopes at once. Tokens never gain scopes they were not issued with.
Limits
Section titled “Limits”| Limit | Value |
|---|---|
| Manifest size | 64 KB |
| Tools | 50 |
| Slash commands | 25 |
| Event subscriptions | 30 |
| Tool schema size | 8 KB each |
| Tool schema depth | 5 |
maxLength on schema strings |
≤ 4096 |
maxItems on schema arrays |
≤ 200 |
| Incoming webhooks per installation | 1–20 |
| OAuth redirect URLs | 1–10 |
The safe JSON Schema subset
Section titled “The safe JSON Schema subset”Tool input and output schemas (later phase) use a restricted JSON Schema, so that Ketvia can validate every argument and result without running remote regular expressions or following references:
- Allowed keywords:
type(one ofobject,string,integer,number,boolean,array),properties,required,additionalProperties,enum(1 to 100 primitive values),const,minimum,maximum,minLength,maxLength,minItems,maxItems,items,description,title(≤ 1000 characters) andx-ketvia-dataClass(aggregate,standard,personalorsensitive). formatonly on strings, one ofdate,date-time,uuid,email,uri.- Objects must set
"additionalProperties": false; at most 50 properties, named^[A-Za-z_][A-Za-z0-9_]{0,63}$. - Strings must set
maxLength(≤ 4096). Arrays must setminItemsandmaxItems(≤ 200) anditems. - Not allowed:
$ref,pattern,oneOf,anyOf,allOf,ifand any other keyword. - Depth at most 5, at most 8 KB per schema, and the top level is an object.