Build and run a workflow
Core concepts
A workflow is a versioned graph of actions and conditions. A block performs one step. An adapter calls a concrete external API from Buywell. A module connects Buywell to a platform and supplies its own events and blocks.
- A draft can be edited and tested.
- A published revision is immutable.
- A connection links a published workflow to an exact module event version.
Your first workflow
A new workflow starts with the Start block. Add actions and conditions from the left panel, connect them, and lead every path to a successful or failed result.
Workflow inputs are declared separately. A field may use a manual value, a workflow input, or an earlier step result.
- Use a clear workflow name.
- Configure every required block field.
- Lead every branch to a terminal block.
Validate and publish
Validation reports structural and compatibility problems. A test run uses your sample values and shows the ordered result of every step.
Publishing freezes an exact revision. Later changes remain in a new draft; selecting an older published revision is the rollback action.
- Resolve issues in the single diagnostics area.
- Test the successful and alternative branches.
- Publish only after a test.
Events and connections
After publishing, choose an event from an installed module. Buywell exposes only trigger conditions and data sources declared by that module.
Compatibility is checked before enabling: package version, event, blocks, and the connected Edge driver must match.
- Trigger conditions filter events.
- Data fields populate workflow inputs.
- A connection is enabled only after successful validation.
Run history
History shows the final result, ordered steps, duration, and the point of failure. Temporary errors follow the declared retry policy; permanent failures finish the run and remain visible.
- Inspect the stopped step input and result.
- Confirm the required module version is connected.
- Never put passwords or access keys into ordinary workflow fields.
Build a module for Buywell
Module package
A module is distributed as one ZIP archive using the .buywell-module.zip suffix. It contains manifest.json, one Edge driver, the required Russian Markdown installation guide, optional localized readme and changelog files, and optional local assets.
- Manifest paths are relative to the archive.
- Driver URLs and hand-written hashes are not required.
- A published package version is immutable.
manifest.json specification
The manifest is the package's strict versioned contract. It declares module identity, packaged files, events, exposed data, nodes, and implementations of neutral actions.
In an Edge package, the module supplies the Russian and English label for every configuration field through configuration_field; Edge does not guess field meaning from its name.
Copy the minimal valid example, then check every field against the reference. Unknown fields are rejected, while related paths, types, namespaces, and versions are validated together.
Everything manifest.json may declare
Every example on this page is checked by the same contract used when a package is installed. Start with the compact example and use the field reference for events, data sources, nodes, and compatibility rules.
For Buywell Edge, the Python SDK generates Manifest v2, schemas, file inventory, digest, and signature from typed declarations. A signed adapter-driver supplies its managed adapter and operation fields directly when Edge connects; Buywell verifies the signature before showing its user-scoped blocks. Existing modules can preserve the entire v1 manifest as their compatibility contract.
{
"schemaVersion": 1,
"protocolVersion": "1.0.0",
"module": {
"id": "example.delivery",
"version": "1.0.0",
"displayName": "Example Delivery",
"description": "A minimal module package example.",
"publisher": "Example developer",
"supportedPlatforms": [
"Example Platform"
]
},
"nodes": [
{
"type": "example.delivery/send-message",
"version": "1.0.0",
"kind": "action",
"displayName": "Send message",
"localization": {
"ru": {
"displayName": "Отправить сообщение"
},
"en": {
"displayName": "Send message"
}
},
"inputSchema": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
},
"required": [
"message"
],
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"properties": {},
"required": [],
"additionalProperties": false
},
"configSchema": {
"type": "object",
"properties": {},
"required": [],
"additionalProperties": false
},
"requiredEventContext": [
{
"eventType": "commerce.purchase.created",
"eventVersion": "1.0.0",
"source": "scope",
"path": "conversationId"
}
],
"ui": {
"category": "Messages",
"icon": "message"
}
}
],
"events": [
{
"type": "commerce.purchase.created",
"version": "1.0.0",
"displayName": "Purchase received",
"localization": {
"ru": {
"displayName": "Получена покупка"
},
"en": {
"displayName": "Purchase received"
}
},
"payloadSchema": {
"type": "object",
"properties": {
"purchaseId": {
"type": "string"
},
"recipient": {
"type": "string"
}
},
"required": [
"purchaseId",
"recipient"
],
"additionalProperties": false
},
"scopeSchema": {
"type": "object",
"properties": {
"conversationId": {
"type": "string"
}
},
"required": [
"conversationId"
],
"additionalProperties": false
},
"selectors": [],
"bindingFields": [
{
"id": "recipient",
"source": "payload",
"path": "recipient",
"valueSchema": {
"type": "string"
},
"displayName": "Recipient",
"localization": {
"ru": {
"displayName": "Получатель"
},
"en": {
"displayName": "Recipient"
}
},
"recommended": true,
"availability": "always"
}
],
"identityFields": [
"purchaseId"
],
"ui": {
"category": "Sales",
"icon": "cart"
}
}
],
"abstractions": [
{
"abstractionId": "messaging.send-in-context",
"abstractionVersion": "1.0.0",
"nodeType": "example.delivery/send-message",
"nodeVersion": "1.0.0"
}
],
"package": {
"branding": {
"icon": "assets/icon.png"
},
"artifact": {
"path": "edge/driver.py",
"filename": "driver.py"
},
"guides": {
"installation": {
"ru": "guides/install.ru.md",
"en": "guides/install.en.md"
},
"readme": {
"ru": "guides/README.ru.md",
"en": "guides/README.en.md"
},
"changelog": {
"ru": "guides/CHANGELOG.ru.md",
"en": "guides/CHANGELOG.en.md"
}
},
"compatibility": {
"environments": [
"Example Runtime 1.x"
]
},
"release": {
"critical": false
}
}
}What every field controls and which values it accepts
Root manifest7 fields
Package identity, contents, and public capabilities.
schemaVersion1requiredMay be omitted; parsing and the canonical manifest set it to 1. · default: 1
protocolVersion"1.0.0"requiredMay be omitted; parsing and the canonical manifest set it to 1.0.0. · default: "1.0.0"
moduleobjectrequiredIdentity, publisher, and supported platforms. · unknown fields are rejected
nodesarrayrequiredBlocks owned by this package. · maximum items: 100
eventsarrayVersioned module events. · maximum items: 100
abstractionsarrayImplementations of platform-neutral contracts. · maximum items: 100
packageobjectArchive files, compatibility, and release metadata. · unknown fields are rejected
module10 fields
Purpose, accepted values, and validation limits for this part of the manifest.
module.idstringrequiredLowercase dot/dash-separated segments, such as example.delivery. · pattern: ^[a-z0-9]+(?:[.-][a-z0-9]+)+$
module.versionstringrequiredx.y.z with an optional prerelease suffix. · pattern: ^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$
module.displayNamestringrequiredBase name; RU/EN localization may replace it. · minimum length: 1 · maximum length: 120
module.descriptionstringOptional short user-facing description. · maximum length: 2000
module.publisherstringrequiredPackage publisher name. · minimum length: 1 · maximum length: 160
module.supportedPlatformsarrayrequiredHuman-readable supported platform names. · minimum items: 1 · maximum items: 50
module.documentationobjectOptional HTTP(S) homepageUrl, supportUrl, and sourceUrl. · unknown fields are rejected
module.documentation.homepageUrlstringLinks to the module or publisher homepage. · maximum length: 2048 · format: uri
module.documentation.supportUrlstringTells users where to get support for the module. · maximum length: 2048 · format: uri
module.documentation.sourceUrlstringLinks to the module source when the publisher makes it available. · maximum length: 2048 · format: uri
nodes[]31 fields
Purpose, accepted values, and validation limits for this part of the manifest.
nodes[].typestringrequiredMust begin with the exact module.id/ namespace. · pattern: ^[a-z0-9]+(?:[.-][a-z0-9]+)*\/[a-z][a-z0-9.-]*$
nodes[].versionstringrequiredNode contract version. · pattern: ^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$
nodes[].kind"action" | "condition"requiredcondition requires branches; action forbids branches.
nodes[].displayNamestringrequireddisplayName is required; description and RU/EN localization are optional. · minimum length: 1 · maximum length: 120
nodes[].descriptionstringdisplayName is required; description and RU/EN localization are optional. · maximum length: 2000
nodes[].localizationobjectdisplayName is required; description and RU/EN localization are optional. · unknown fields are rejected
nodes[].localization.ruobjectRequired non-empty UTF-8 Markdown guide. · unknown fields are rejected
nodes[].localization.ru.displayNamestringdisplayName is required; description and RU/EN localization are optional. · minimum length: 1 · maximum length: 120
nodes[].localization.ru.descriptionstringdisplayName is required; description and RU/EN localization are optional. · maximum length: 2000
nodes[].localization.enobjectOptional translation; RU is the fallback. · unknown fields are rejected
nodes[].localization.en.displayNamestringdisplayName is required; description and RU/EN localization are optional. · minimum length: 1 · maximum length: 120
nodes[].localization.en.descriptionstringdisplayName is required; description and RU/EN localization are optional. · maximum length: 2000
nodes[].inputSchemavaluerequiredAction or condition inputs.
nodes[].outputSchemavaluerequiredDefault to closed empty objects. · default: {"type":"object","properties":{},"required":[],"additionalProperties":false}
nodes[].configSchemavaluerequiredDefault to closed empty objects. · default: {"type":"object","properties":{},"required":[],"additionalProperties":false}
nodes[].requiredEventContextarrayExisting eventType@version and payload/scope paths. · maximum items: 100
nodes[].requiredEventContext[].eventTypestringrequiredSelects the event whose context the node needs to run. · pattern: ^[a-z0-9]+(?:[.-][a-z0-9]+)+$
nodes[].requiredEventContext[].eventVersionstringrequiredPins the exact required event version. · pattern: ^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$
nodes[].requiredEventContext[].source"payload" | "scope"requiredThe path must exist in the selected schema.
nodes[].requiredEventContext[].pathstringrequiredThe single Edge driver stored in the archive. · minimum length: 1 · maximum length: 512
nodes[].branchesarraycondition only; every branch contains id and label. · minimum items: 2 · maximum items: 20
nodes[].branches[].idstringrequiredLowercase dot/dash-separated segments, such as example.delivery. · pattern: ^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$
nodes[].branches[].labelstringrequiredNames a condition output as users see it in the editor. · minimum length: 1 · maximum length: 120
nodes[].retryPolicyobjectmaxAttempts, initialBackoffMs, and maxBackoffMs within contract limits. · unknown fields are rejected
nodes[].retryPolicy.maxAttemptsintegerrequiredLimits the total number of node execution attempts. · ≥ 1 · ≤ 10
nodes[].retryPolicy.initialBackoffMsintegerrequiredSets the delay before the first node retry. · ≥ 0 · ≤ 300000
nodes[].retryPolicy.maxBackoffMsintegerrequiredCaps the delay between node retries. · ≥ 0 · ≤ 3600000
nodes[].uiobjectrequiredcategory, #RRGGBB color, and icon. · default: {"category":"Other"} · unknown fields are rejected
nodes[].ui.categorystringrequiredPlaces the node in a section of the block library. · default: "Other" · minimum length: 1 · maximum length: 80
nodes[].ui.colorstringSets the node accent color in the editor. · pattern: ^#[0-9A-Fa-f]{6}$
nodes[].ui.iconstringPNG, JPEG, or WebP with content matching its extension. · minimum length: 1 · maximum length: 80
events[]106 fields
Purpose, accepted values, and validation limits for this part of the manifest.
events[].typestringrequiredVersioned event identity. · pattern: ^[a-z0-9]+(?:[.-][a-z0-9]+)+$
events[].versionstringrequiredVersioned event identity. · pattern: ^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$
events[].displayNamestringrequireddisplayName is required; description is optional and limited to 2,000 characters. · minimum length: 1 · maximum length: 120
events[].descriptionstringdisplayName is required; description is optional and limited to 2,000 characters. · maximum length: 2000
events[].localizationobjectdisplayName is required; description and RU/EN localization are optional. · unknown fields are rejected
events[].localization.ruobjectRequired non-empty UTF-8 Markdown guide. · unknown fields are rejected
events[].localization.ru.displayNamestringdisplayName is required; description is optional and limited to 2,000 characters. · minimum length: 1 · maximum length: 120
events[].localization.ru.descriptionstringdisplayName is required; description is optional and limited to 2,000 characters. · maximum length: 2000
events[].localization.enobjectOptional translation; RU is the fallback. · unknown fields are rejected
events[].localization.en.displayNamestringdisplayName is required; description is optional and limited to 2,000 characters. · minimum length: 1 · maximum length: 120
events[].localization.en.descriptionstringdisplayName is required; description is optional and limited to 2,000 characters. · maximum length: 2000
events[].payloadSchemavaluerequiredEvent body; every identityFields path must exist and be required.
events[].scopeSchemavaluerequiredExecution context. Defaults to a closed empty object. · default: {"type":"object","properties":{},"required":[],"additionalProperties":false}
events[].selectorsarrayrequiredLaunch filter fields; defaults to []. · default: [] · maximum items: 100
events[].selectors[].idstringrequiredLowercase dot/dash-separated segments, such as example.delivery. · pattern: ^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$
events[].selectors[].displayNamestringrequireddisplayName is required; description is optional and limited to 2,000 characters. · minimum length: 1 · maximum length: 120
events[].selectors[].source"payload" | "scope"requiredThe path must exist in the selected schema.
events[].selectors[].pathstringrequiredThe single Edge driver stored in the archive. · minimum length: 1 · maximum length: 512
events[].selectors[].operatorsarrayrequiredexists, equals, not-equals, in, contains, starts-with, ends-with, or matches. · minimum items: 1 · maximum items: 8
events[].selectors[].localizationobjectdisplayName is required; description and RU/EN localization are optional. · unknown fields are rejected
events[].selectors[].localization.ruobjectRequired non-empty UTF-8 Markdown guide. · unknown fields are rejected
events[].selectors[].localization.ru.displayNamestringdisplayName is required; description is optional and limited to 2,000 characters. · minimum length: 1 · maximum length: 120
events[].selectors[].localization.ru.descriptionstringdisplayName is required; description is optional and limited to 2,000 characters. · maximum length: 2000
events[].selectors[].localization.enobjectOptional translation; RU is the fallback. · unknown fields are rejected
events[].selectors[].localization.en.displayNamestringdisplayName is required; description is optional and limited to 2,000 characters. · minimum length: 1 · maximum length: 120
events[].selectors[].localization.en.descriptionstringdisplayName is required; description is optional and limited to 2,000 characters. · maximum length: 2000
events[].bindingFieldsarrayTyped payload/scope values exposed as input sources. · maximum items: 200
events[].bindingFields[].idstringrequiredLowercase dot/dash-separated segments, such as example.delivery. · pattern: ^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$
events[].bindingFields[].source"payload" | "scope"requiredThe path must exist in the selected schema.
events[].bindingFields[].pathstringrequiredThe single Edge driver stored in the archive. · minimum length: 1 · maximum length: 512
events[].bindingFields[].valueSchemavaluerequiredType must match the declared path type.
events[].bindingFields[].displayNamestringrequireddisplayName is required; description is optional and limited to 2,000 characters. · minimum length: 1 · maximum length: 120
events[].bindingFields[].descriptionstringdisplayName is required; description is optional and limited to 2,000 characters. · maximum length: 2000
events[].bindingFields[].localizationobjectdisplayName is required; description and RU/EN localization are optional. · unknown fields are rejected
events[].bindingFields[].localization.ruobjectRequired non-empty UTF-8 Markdown guide. · unknown fields are rejected
events[].bindingFields[].localization.ru.displayNamestringdisplayName is required; description is optional and limited to 2,000 characters. · minimum length: 1 · maximum length: 120
events[].bindingFields[].localization.ru.descriptionstringdisplayName is required; description is optional and limited to 2,000 characters. · maximum length: 2000
events[].bindingFields[].localization.enobjectOptional translation; RU is the fallback. · unknown fields are rejected
events[].bindingFields[].localization.en.displayNamestringdisplayName is required; description is optional and limited to 2,000 characters. · minimum length: 1 · maximum length: 120
events[].bindingFields[].localization.en.descriptionstringdisplayName is required; description is optional and limited to 2,000 characters. · maximum length: 2000
events[].bindingFields[].categorystringGroups the value in the data-source picker. · minimum length: 1 · maximum length: 80
events[].bindingFields[].orderintegerOrders the value among other event data sources. · ≥ 0 · ≤ 10000
events[].bindingFields[].recommendedbooleanUI hints and data-handling metadata.
events[].bindingFields[].nullablebooleanUI hints and data-handling metadata.
events[].bindingFields[].availability"always" | "when-present"requiredDefaults to always. · default: "always"
events[].bindingFields[].sensitivebooleanUI hints and data-handling metadata.
events[].bindingFields[].keyedobjectFor an object path, declares guardPath and guardParameter for a parameterized string value. · unknown fields are rejected
events[].bindingFields[].keyed.guardPathstringrequiredChecks context before reading a parameterized key from an object field. · minimum length: 1 · maximum length: 512
events[].bindingFields[].keyed.guardParameterstringrequiredNames the binding parameter whose value must match guardPath. · pattern: ^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$
events[].bindingCatalogsarrayDeclares category, product, or other scope catalogs from which users can select event context. · maximum items: 20
events[].bindingCatalogs[].idstringrequiredLowercase dot/dash-separated segments, such as example.delivery. · pattern: ^[a-z0-9]+(?:[.-][a-z0-9]+)+$
events[].bindingCatalogs[].versionstringrequiredVersioned event identity. · pattern: ^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$
events[].bindingCatalogs[].displayNamestringrequireddisplayName is required; description is optional and limited to 2,000 characters. · minimum length: 1 · maximum length: 120
events[].bindingCatalogs[].localizationobjectdisplayName is required; description and RU/EN localization are optional. · unknown fields are rejected
events[].bindingCatalogs[].localization.ruobjectRequired non-empty UTF-8 Markdown guide. · unknown fields are rejected
events[].bindingCatalogs[].localization.ru.displayNamestringdisplayName is required; description is optional and limited to 2,000 characters. · minimum length: 1 · maximum length: 120
events[].bindingCatalogs[].localization.ru.descriptionstringdisplayName is required; description is optional and limited to 2,000 characters. · maximum length: 2000
events[].bindingCatalogs[].localization.enobjectOptional translation; RU is the fallback. · unknown fields are rejected
events[].bindingCatalogs[].localization.en.displayNamestringdisplayName is required; description is optional and limited to 2,000 characters. · minimum length: 1 · maximum length: 120
events[].bindingCatalogs[].localization.en.descriptionstringdisplayName is required; description is optional and limited to 2,000 characters. · maximum length: 2000
events[].bindingCatalogs[].scopeobjectrequiredDefines the selector and parameter that bind a catalog choice to event context. · unknown fields are rejected
events[].bindingCatalogs[].scope.displayNamestringrequireddisplayName is required; description is optional and limited to 2,000 characters. · minimum length: 1 · maximum length: 120
events[].bindingCatalogs[].scope.localizationobjectdisplayName is required; description and RU/EN localization are optional. · unknown fields are rejected
events[].bindingCatalogs[].scope.localization.ruobjectRequired non-empty UTF-8 Markdown guide. · unknown fields are rejected
events[].bindingCatalogs[].scope.localization.ru.displayNamestringdisplayName is required; description is optional and limited to 2,000 characters. · minimum length: 1 · maximum length: 120
events[].bindingCatalogs[].scope.localization.ru.descriptionstringdisplayName is required; description is optional and limited to 2,000 characters. · maximum length: 2000
events[].bindingCatalogs[].scope.localization.enobjectOptional translation; RU is the fallback. · unknown fields are rejected
events[].bindingCatalogs[].scope.localization.en.displayNamestringdisplayName is required; description is optional and limited to 2,000 characters. · minimum length: 1 · maximum length: 120
events[].bindingCatalogs[].scope.localization.en.descriptionstringdisplayName is required; description is optional and limited to 2,000 characters. · maximum length: 2000
events[].bindingCatalogs[].scope.selectorIdstringrequiredReferences an event selector with the equals operator that constrains the selected scope. · pattern: ^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$
events[].bindingCatalogs[].scope.guardParameterstringrequiredNames the parameter that passes the selected catalog value into keyed fields. · pattern: ^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$
events[].bindingCatalogs[].valueFieldIdstringrequiredReferences the keyed field containing a catalog item's internal value. · pattern: ^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$
events[].bindingCatalogs[].choiceFieldIdstringrequiredReferences the keyed field containing the catalog choice shown to users. · pattern: ^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$
events[].identityFieldsarrayrequiredPayload paths that form event identity. · minimum items: 1 · maximum items: 20
events[].inputResolversarrayVersioned immediate/deferred data sources. · maximum items: 50
events[].inputResolvers[].idstringrequiredLowercase dot/dash-separated segments, such as example.delivery. · pattern: ^[a-z0-9]+(?:[.-][a-z0-9]+)+$
events[].inputResolvers[].versionstringrequiredVersioned event identity. · pattern: ^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$
events[].inputResolvers[].abstractionIdstringOptional exact Buywell abstraction; both fields are declared together. · pattern: ^[a-z0-9]+(?:[.-][a-z0-9]+)+$
events[].inputResolvers[].abstractionVersionstringOptional exact Buywell abstraction; both fields are declared together. · pattern: ^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$
events[].inputResolvers[].displayNamestringrequireddisplayName is required; description is optional and limited to 2,000 characters. · minimum length: 1 · maximum length: 120
events[].inputResolvers[].descriptionstringdisplayName is required; description is optional and limited to 2,000 characters. · maximum length: 2000
events[].inputResolvers[].outputSchemavaluerequiredExact returned value type.
events[].inputResolvers[].parameterSchemavalueFor an abstraction, it must exactly match its versioned contract.
events[].inputResolvers[].mode"immediate" | "deferred"requiredProduction executes deferred; immediate is not activated as a remote job.
events[].inputResolvers[].localizationobjectdisplayName is required; description and RU/EN localization are optional. · unknown fields are rejected
events[].inputResolvers[].localization.ruobjectRequired non-empty UTF-8 Markdown guide. · unknown fields are rejected
events[].inputResolvers[].localization.ru.displayNamestringdisplayName is required; description is optional and limited to 2,000 characters. · minimum length: 1 · maximum length: 120
events[].inputResolvers[].localization.ru.descriptionstringdisplayName is required; description is optional and limited to 2,000 characters. · maximum length: 2000
events[].inputResolvers[].localization.enobjectOptional translation; RU is the fallback. · unknown fields are rejected
events[].inputResolvers[].localization.en.displayNamestringdisplayName is required; description is optional and limited to 2,000 characters. · minimum length: 1 · maximum length: 120
events[].inputResolvers[].localization.en.descriptionstringdisplayName is required; description is optional and limited to 2,000 characters. · maximum length: 2000
events[].inputResolvers[].requiredContextarrayEvery payload/scope path exists and is guaranteed required. · maximum items: 50
events[].inputResolvers[].requiredContext[].source"payload" | "scope"requiredThe path must exist in the selected schema.
events[].inputResolvers[].requiredContext[].pathstringrequiredThe single Edge driver stored in the archive. · minimum length: 1 · maximum length: 512
events[].inputResolvers[].timeoutMsintegerOptional wait limit. · ≥ 100 · ≤ 300000
events[].inputResolvers[].retryobjectmaxAttempts 1…10 and initialBackoffMs 0…300000. · unknown fields are rejected
events[].inputResolvers[].retry.maxAttemptsintegerrequiredLimits attempts to obtain deferred data. · ≥ 1 · ≤ 10
events[].inputResolvers[].retry.initialBackoffMsintegerrequiredSets the delay before retrying deferred data resolution. · ≥ 0 · ≤ 300000
events[].inputResolvers[].sensitivebooleanUI hints and data-handling metadata.
events[].inputResolvers[].uiobjectcategory defaults to Other; icon is optional. · unknown fields are rejected
events[].inputResolvers[].ui.categorystringGroups the data resolver in the editor. · minimum length: 1 · maximum length: 80
events[].inputResolvers[].ui.orderintegerOrders the data resolver in the editor. · ≥ 0 · ≤ 10000
events[].inputResolvers[].ui.recommendedbooleanUI hints and data-handling metadata.
events[].uiobjectrequiredcategory defaults to Other; icon is optional. · default: {"category":"Other"} · unknown fields are rejected
events[].ui.categorystringrequiredPlaces the event in a section of the trigger picker. · default: "Other" · minimum length: 1 · maximum length: 80
events[].ui.iconstringPNG, JPEG, or WebP with content matching its extension. · minimum length: 1 · maximum length: 80
abstractions[]4 fields
Purpose, accepted values, and validation limits for this part of the manifest.
abstractions[].abstractionIdstringrequiredSelects the stable neutral-action contract implemented by the module. · pattern: ^[a-z0-9]+(?:[.-][a-z0-9]+)+$
abstractions[].abstractionVersionstringrequiredPins the exact version of that neutral-action contract. · pattern: ^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$
abstractions[].nodeTypestringrequiredReferences an existing node owned by this module.id. · pattern: ^[a-z0-9]+(?:[.-][a-z0-9]+)*\/[a-z][a-z0-9.-]*$
abstractions[].nodeVersionstringrequiredReferences an existing node owned by this module.id. · pattern: ^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$
package25 fields
Purpose, accepted values, and validation limits for this part of the manifest.
package.brandingobjectDescribes the module visuals included in the archive. · unknown fields are rejected
package.branding.iconstringrequiredPNG, JPEG, or WebP with content matching its extension. · minimum length: 1 · maximum length: 240
package.artifactobjectrequiredPoints to the executable Edge driver for this module version. · unknown fields are rejected
package.artifact.pathstringrequiredThe single Edge driver stored in the archive. · minimum length: 1 · maximum length: 240
package.artifact.filenamestringDownload filename; never a URL. · minimum length: 1 · maximum length: 180
package.guidesobjectrequiredCollects installation and maintenance guidance for the module. · unknown fields are rejected
package.guides.installationobjectrequiredContains the required Russian installation guide and optional English translation. · unknown fields are rejected
package.guides.installation.rustringrequiredRequired non-empty UTF-8 Markdown guide. · minimum length: 1 · maximum length: 240
package.guides.installation.enstringOptional translation; RU is the fallback. · minimum length: 1 · maximum length: 240
package.guides.readmeobjectContains the localized module overview shown in About. · unknown fields are rejected
package.guides.readme.rustringrequiredPoints to the required Russian About Markdown when a readme is declared. · minimum length: 1 · maximum length: 240
package.guides.readme.enstringPoints to the optional English readme; the Russian file is the fallback. · minimum length: 1 · maximum length: 240
package.guides.changelogobjectContains the localized, version-by-version user changelog. · unknown fields are rejected
package.guides.changelog.rustringrequiredPoints to the required Russian changelog Markdown when a changelog is declared. · minimum length: 1 · maximum length: 240
package.guides.changelog.enstringPoints to the optional English changelog; the Russian file is the fallback. · minimum length: 1 · maximum length: 240
package.guides.updateUrlstringLinks to module update instructions. · maximum length: 2048 · format: uri
package.guides.rollbackUrlstringLinks to rollback instructions. · maximum length: 2048 · format: uri
package.guides.troubleshootingUrlstringLinks to troubleshooting guidance. · maximum length: 2048 · format: uri
package.guides.removalUrlstringLinks to safe module removal instructions. · maximum length: 2048 · format: uri
package.compatibilityobjectrequiredDeclares the service versions and environments where the package can run. · unknown fields are rejected
package.compatibility.minimumBuywellVersionstringOptional minimum compatible service version. · pattern: ^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$
package.compatibility.environmentsarrayrequiredSupported Buywell Edge environments. · minimum items: 1 · maximum items: 30
package.releaseobjectrequiredCarries release importance and changelog information. · default: {"critical":false} · unknown fields are rejected
package.release.criticalbooleanrequiredDefaults to false. · default: false
package.release.changelogUrlstringOptional release changelog. · maximum length: 2048 · format: uri
Neutral actions a module may implement
An abstraction lets a workflow request a familiar action without depending on one platform. A compatible module binds that action to its own node.
messaging.send-in-context@1.0.0actionSend message
Send a message in the current conversation.
- Workflow block
abstract/send-in-context@1.0.0- Inputs
message*- Known implementations
example.delivery/send-message@1.0.0
Extended neutral manifest1 events · 2 nodes
This example demonstrates events, filters, workflow data, resolvers, actions, and conditions executed through Buywell Edge.
{
"schemaVersion": 1,
"protocolVersion": "1.0.0",
"module": {
"id": "example.delivery",
"version": "1.1.0",
"displayName": "Example Delivery",
"description": "A complete production-compatible manifest example.",
"publisher": "Example developer",
"supportedPlatforms": [
"Example Platform"
]
},
"nodes": [
{
"type": "example.delivery/send-message",
"version": "1.0.0",
"kind": "action",
"displayName": "Send message",
"localization": {
"ru": {
"displayName": "Отправить сообщение"
},
"en": {
"displayName": "Send message"
}
},
"inputSchema": {
"type": "object",
"properties": {
"message": {
"type": "string"
}
},
"required": [
"message"
],
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"properties": {},
"required": [],
"additionalProperties": false
},
"configSchema": {
"type": "object",
"properties": {},
"required": [],
"additionalProperties": false
},
"requiredEventContext": [
{
"eventType": "commerce.purchase.created",
"eventVersion": "1.0.0",
"source": "scope",
"path": "conversationId"
}
],
"ui": {
"category": "Messages",
"icon": "message"
}
},
{
"type": "example.delivery/has-recipient",
"version": "1.0.0",
"kind": "condition",
"displayName": "Recipient is present",
"localization": {
"ru": {
"displayName": "Получатель указан"
},
"en": {
"displayName": "Recipient is present"
}
},
"inputSchema": {
"type": "object",
"properties": {
"recipient": {
"type": "string"
}
},
"required": [
"recipient"
],
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"properties": {},
"required": [],
"additionalProperties": false
},
"configSchema": {
"type": "object",
"properties": {},
"required": [],
"additionalProperties": false
},
"branches": [
{
"id": "yes",
"label": "Yes"
},
{
"id": "no",
"label": "No"
}
],
"ui": {
"category": "Checks",
"icon": "question"
}
}
],
"events": [
{
"type": "commerce.purchase.created",
"version": "1.0.0",
"displayName": "Purchase received",
"localization": {
"ru": {
"displayName": "Получена покупка"
},
"en": {
"displayName": "Purchase received"
}
},
"payloadSchema": {
"type": "object",
"properties": {
"purchaseId": {
"type": "string"
},
"recipient": {
"type": "string"
},
"categoryId": {
"type": "string"
},
"customFields": {
"type": "object",
"additionalProperties": true
}
},
"required": [
"purchaseId",
"recipient"
],
"additionalProperties": false
},
"scopeSchema": {
"type": "object",
"properties": {
"conversationId": {
"type": "string"
}
},
"required": [
"conversationId"
],
"additionalProperties": false
},
"selectors": [
{
"id": "category-id",
"displayName": "Category",
"source": "payload",
"path": "categoryId",
"operators": [
"equals"
]
},
{
"id": "recipient",
"displayName": "Recipient",
"source": "payload",
"path": "recipient",
"operators": [
"exists",
"equals",
"contains"
],
"localization": {
"ru": {
"displayName": "Получатель"
},
"en": {
"displayName": "Recipient"
}
}
}
],
"bindingFields": [
{
"id": "recipient",
"source": "payload",
"path": "recipient",
"valueSchema": {
"type": "string"
},
"displayName": "Recipient",
"localization": {
"ru": {
"displayName": "Получатель"
},
"en": {
"displayName": "Recipient"
}
},
"recommended": true,
"availability": "always"
},
{
"id": "custom-field",
"source": "payload",
"path": "customFields",
"valueSchema": {
"type": "string"
},
"displayName": "Custom field",
"localization": {
"ru": {
"displayName": "Дополнительное поле"
},
"en": {
"displayName": "Custom field"
}
},
"availability": "when-present",
"keyed": {
"guardPath": "categoryId",
"guardParameter": "categoryId"
}
}
],
"bindingCatalogs": [
{
"id": "example.categories",
"version": "1.0.0",
"displayName": "Category fields",
"scope": {
"displayName": "Category",
"selectorId": "category-id",
"guardParameter": "categoryId"
},
"valueFieldId": "custom-field",
"choiceFieldId": "custom-field"
}
],
"identityFields": [
"purchaseId"
],
"inputResolvers": [
{
"id": "commerce.recipient-profile",
"version": "1.0.0",
"displayName": "Recipient profile",
"outputSchema": {
"type": "object",
"additionalProperties": true
},
"mode": "deferred",
"localization": {
"ru": {
"displayName": "Профиль получателя"
},
"en": {
"displayName": "Recipient profile"
}
},
"requiredContext": [
{
"source": "scope",
"path": "conversationId"
}
],
"timeoutMs": 30000,
"retry": {
"maxAttempts": 3,
"initialBackoffMs": 1000
},
"ui": {
"category": "Customer data",
"order": 20
}
}
],
"ui": {
"category": "Sales",
"icon": "cart"
}
}
],
"abstractions": [
{
"abstractionId": "messaging.send-in-context",
"abstractionVersion": "1.0.0",
"nodeType": "example.delivery/send-message",
"nodeVersion": "1.0.0"
}
],
"package": {
"branding": {
"icon": "assets/icon.png"
},
"artifact": {
"path": "edge/driver.py",
"filename": "driver.py"
},
"guides": {
"installation": {
"ru": "guides/install.ru.md",
"en": "guides/install.en.md"
},
"readme": {
"ru": "guides/README.ru.md",
"en": "guides/README.en.md"
},
"changelog": {
"ru": "guides/CHANGELOG.ru.md",
"en": "guides/CHANGELOG.en.md"
}
},
"compatibility": {
"environments": [
"Example Runtime 1.x"
]
},
"release": {
"critical": false
}
}
}Minimal archive layout
A conventional archive contains manifest.json, edge/driver.py, and guides/install.ru.md. guides/install.en.md and a PNG/JPEG/WebP icon are optional.
Buywell validates safe paths, sizes, file count, UTF-8 Markdown, image formats, and every referenced file. The digest covers the canonical manifest and archive contents, so ZIP entry order and timestamps do not affect identity.
Events and data
An event declares its version, payload/scope schemas, and required identity fields. Trigger selectors and binding fields are intentionally separate: selectors permit launch filtering, while binding fields expose a typed value as a workflow input.
- Do not expose arbitrary JSON paths in the UI.
- Mark sensitive fields.
- A deferred resolver declares only the event context it actually needs.
Blocks and Edge
An action receives declared inputs/config and returns typed outputs. A condition also selects one declared branch. The Edge driver connects outbound and confirms the exact module ID, version, and package digest.
Buywell persists jobs and may redeliver unfinished work. The driver must honor the idempotency key and echo request correlation.
- Never store credentials in a package.
- Do not treat the connection as execution state.
- Return only values allowed by the output schema.
Install and update
The UI, API, and live registration use the same ZIP validator. A new version is installed alongside the old one and never migrates workflows silently. Rollback selects an already installed exact version.
A package referenced by a draft or published workflow cannot be removed. Installation instructions are always read from the pinned archive rather than an external site.