VirtuousAI
Primitives

Templates

Global blueprints that define action and connection configurations

Templates

Templates are immutable blueprints that define how to configure connections, actions, and automations. They provide structure, validation, and documentation for reusable configurations.

Concept

A template defines:

  • Type — What it configures (connection, action, bundle)
  • Definition — Provider-specific configuration schema
  • Input Schema — JSON Schema for user-provided values
  • Defaults — Default values for inputs
  • Metadata — Display name, description, icon

Key Properties

PropertyDescription
ImmutableOnce published, templates cannot be modified (new version required)
VersionedEach change creates a new version, preserving history
SnapshottedWhen used, a snapshot is stored for audit purposes
Global or Tenant-ScopedMarketplace templates are global; custom templates are org-specific

When you create a connection or action from a template, the template's current state is snapshotted. Even if the template changes later, you know exactly what configuration was used.

Template Types

Connection Templates

Define how to connect to external services:

{
  "slug": "shopify",
  "templateType": "connection",
  "displayName": "Shopify",
  "definition": {
    "provider": "shopify",
    "authMethod": "oauth2",
    "scopes": ["read_orders", "read_products", "read_customers"]
  },
  "inputJsonSchema": {
    "type": "object",
    "properties": {
      "shop_url": {
        "type": "string",
        "description": "Your Shopify store URL (e.g., mystore.myshopify.com)"
      }
    },
    "required": ["shop_url"]
  }
}

Action Templates

Define reusable action configurations:

{
  "slug": "shopify-orders-sync",
  "templateType": "action",
  "kind": "dlt_extract",
  "displayName": "Sync Shopify Orders",
  "definition": {
    "source": "shopify",
    "resources": ["orders", "order_line_items"],
    "incremental": true
  },
  "inputJsonSchema": {
    "type": "object",
    "properties": {
      "start_date": {
        "type": "string",
        "format": "date",
        "description": "Start date for data extraction"
      },
      "full_resync": {
        "type": "boolean",
        "description": "If true, ignore state and extract all data"
      }
    }
  },
  "inputDefaults": {
    "full_resync": false
  }
}

Bundle Templates

Package multiple templates together for quick deployment:

{
  "slug": "ecommerce-starter",
  "templateType": "bundle",
  "displayName": "E-commerce Starter Kit",
  "definition": {
    "components": [
      { "type": "connection", "slug": "shopify" },
      { "type": "action", "slug": "shopify-orders-sync" },
      { "type": "action", "slug": "shopify-products-sync" },
      { "type": "automation", "slug": "daily-shopify-sync" }
    ]
  }
}

Template Lifecycle

StatusDescriptionUsable?
DRAFTIn development, can be editedNo
PUBLISHEDLive and available for useYes
DEPRECATEDStill works but discouragedYes (with warning)
ARCHIVEDNo longer availableNo

Marketplace vs Custom

Scopetenant_idDescription
MarketplaceNULLGlobal templates available to all organizations
CustomUUIDPrivate templates for a specific organization

Using Marketplace Templates

# List available templates
vai templates list --type connection

# Create connection from template
vai connections create \
  --template shopify \
  --name "Production Shopify" \
  --input '{"shop_url": "mystore.myshopify.com"}'

Creating Custom Templates

# Create a custom template for your org
vai templates create \
  --type action \
  --slug my-custom-sync \
  --definition '{"source": "shopify", "resources": ["orders"]}' \
  --input-schema '{"type": "object", "properties": {...}}'

Template Resolution

When referencing a template, VirtuousAI checks:

  1. Tenant templates — Custom templates for your organization
  2. Marketplace templates — Global templates if no tenant match

This allows organizations to override marketplace templates with custom versions.

Snapshotting

When you use a template to create a connection or action:

  1. The template's current definition and inputJsonSchema are copied
  2. This snapshot is stored with the created resource
  3. Future template changes don't affect existing resources
{
  "connection": {
    "id": "conn_abc123",
    "templateId": "tmpl_xyz",
    "templateSnapshot": {
      "version": 3,
      "definition": {...},
      "snapshotAt": "2026-01-22T10:00:00Z"
    }
  }
}

Best Practices

  1. Use semantic versioning — Increment version for breaking changes
  2. Document inputs — Add descriptions to all input schema properties
  3. Provide defaults — Set sensible defaults for optional inputs
  4. Deprecate gracefully — Mark templates as deprecated before archiving
  5. Test before publishing — Validate templates work in draft status first

OpenAPI Reference

For detailed endpoint schemas and response formats:

On this page