Skip to main content

Manifests API

The Manifests API provides endpoints for managing team manifests - declarative configurations that define composable AI teams with versioned components.

Overview

Team manifests follow the "npm for AI agents" paradigm. They allow you to:

  • Validate manifest syntax before deploying
  • Resolve component versions without deploying (dry run)
  • Deploy teams from manifests
  • Upgrade components to newer versions
  • Rollback to previous versions
  • Export current team state as manifest

Endpoints Summary

MethodEndpointDescription
POST/manifests/validateValidate manifest syntax
POST/manifests/resolveResolve versions (dry run)
POST/manifests/deployDeploy team from manifest
GET/manifestsList all deployments
GET/manifests/:deployIdGet deployment details
GET/manifests/:deployId/exportExport as manifest
POST/manifests/:deployId/upgradeUpgrade components
POST/manifests/:deployId/rollbackRollback component
GET/manifests/deploymentsList deployments
GET/manifests/deployments/:teamSlugGet deployment by slug
GET/manifests/deployments/:teamSlug/manifestExport manifest
GET/manifests/deployments/:teamSlug/lockfileExport lock file
POST/manifests/deployments/:teamSlug/upgradeUpgrade deployment
POST/manifests/components/:type/:id/rollbackRollback component

Validation

Validate Manifest

Validate a manifest without deploying. Returns syntax errors and warnings.

POST /api/manifests/validate
Content-Type: application/json
Authorization: Bearer <token>

{
"manifest": {
"$schema": "https://meetloyd.com/schemas/team.manifest.json",
"name": "My Team",
"slug": "my-team",
"version": "1.0.0",
"components": {
"agents": [
{
"ref": "store://agents/sdr-agent",
"version": "^1.0.0",
"localId": "sdr"
}
]
}
}
}

Response (valid):

{
"valid": true,
"errors": [],
"warnings": []
}

Response (invalid):

{
"valid": false,
"errors": [
{
"path": "components.agents[0].ref",
"message": "Invalid component reference format"
}
],
"warnings": [
{
"path": "version",
"message": "Using caret version range allows minor updates"
}
]
}

Resolution

Resolve Manifest (Dry Run)

Resolve all component versions without deploying. Returns what the lock file would look like.

POST /api/manifests/resolve
Content-Type: application/json
Authorization: Bearer <token>

{
"manifest": {
"name": "Sales Team",
"slug": "sales-team",
"version": "1.0.0",
"components": {
"agents": [
{
"ref": "store://agents/sdr-agent",
"version": "^1.0.0",
"localId": "sdr"
}
],
"skills": [
{
"ref": "store://skills/salesforce-crm",
"version": "^3.0.0"
}
]
}
}
}

Response:

{
"success": true,
"lockFile": {
"manifestVersion": "1.0.0",
"resolvedAt": "2026-01-15T10:30:00Z",
"checksum": "sha256:abc123...",
"components": {
"agents": {
"store://agents/sdr-agent": {
"ref": "store://agents/sdr-agent",
"resolvedVersion": "1.2.3",
"configHash": "sha256:def456..."
}
},
"skills": {
"store://skills/salesforce-crm": {
"ref": "store://skills/salesforce-crm",
"resolvedVersion": "3.1.2",
"configHash": "sha256:ghi789..."
}
}
}
},
"errors": [],
"warnings": []
}

Response (resolution failed):

{
"success": false,
"lockFile": null,
"errors": [
{
"component": "store://agents/unknown-agent",
"message": "Component not found in store"
}
],
"warnings": []
}

Deployment

Deploy Team from Manifest

Deploy a complete team from a manifest configuration.

POST /api/manifests/deploy
Content-Type: application/json
Authorization: Bearer <token>

{
"manifest": {
"name": "Enterprise Sales",
"slug": "enterprise-sales",
"version": "2.0.0",
"description": "AI-powered enterprise sales team",
"components": {
"agents": [
{
"ref": "store://agents/sdr-agent",
"version": "1.2.3",
"locked": true,
"localId": "sdr"
},
{
"ref": "store://agents/ae-agent",
"version": "^1.0.0",
"localId": "ae",
"customizations": {
"contextPromptTemplate": "You specialize in {{industry}} sales."
}
}
],
"skills": [
{
"ref": "store://skills/salesforce-crm",
"version": "3.1.2",
"locked": true
}
],
"avatars": [
{
"ref": "external://heygen/professional-sarah",
"localId": "sarah"
}
]
},
"orchestration": {
"mode": "hierarchical",
"entryAgentId": "sdr",
"routing": {
"intentRouting": [
{
"intent": "pricing_inquiry",
"targetAgentId": "ae",
"priority": 1
}
],
"fallbackAgentId": "sdr"
}
}
},
"options": {
"dryRun": false,
"force": false,
"notes": "Initial deployment for Q1 sales push"
}
}

Options:

OptionTypeDefaultDescription
dryRunbooleanfalseSimulate deployment without changes
forcebooleanfalseOverride existing deployment
skipResolutionbooleanfalseSkip version resolution
notesstring-Deployment notes for audit

Response:

{
"success": true,
"deployment": {
"id": "deploy_abc123",
"teamSlug": "enterprise-sales",
"teamVersion": "2.0.0",
"status": "active",
"deployedAt": "2026-01-15T10:30:00Z"
},
"createdAgents": [
{ "id": "agent_sdr123", "localId": "sdr", "name": "SDR Agent" },
{ "id": "agent_ae456", "localId": "ae", "name": "AE Agent" }
],
"createdSkills": [
{ "id": "skill_sf789", "name": "Salesforce CRM" }
],
"createdAvatars": [
{ "id": "avatar_sarah", "localId": "sarah", "provider": "heygen" }
]
}

Response (failed):

{
"success": false,
"errors": [
{
"code": "COMPONENT_NOT_FOUND",
"message": "Agent store://agents/unknown not found"
}
],
"resolution": null
}

Deployment Management

List Deployments

Get all team deployments for your tenant.

GET /api/manifests
Authorization: Bearer <token>

Query Parameters:

ParameterTypeDefaultDescription
limitinteger50Max results (1-100)
offsetinteger0Pagination offset
statusstring-Filter by status

Response:

{
"deploys": [
{
"id": "deploy_abc123",
"tenantId": "tenant_xyz",
"teamSlug": "enterprise-sales",
"teamVersion": "2.0.0",
"status": "active",
"deployedAt": "2026-01-15T10:30:00Z",
"deployedBy": "user_123",
"lastResolvedAt": "2026-01-15T10:30:00Z",
"componentCount": 4,
"hasUpdates": true
}
],
"total": 1
}

Get Deployment Details

Get full details of a specific deployment.

GET /api/manifests/:deployId
Authorization: Bearer <token>

Response:

{
"manifest": {
"name": "Enterprise Sales",
"slug": "enterprise-sales",
"version": "2.0.0",
"components": { ... }
},
"lockFile": {
"manifestVersion": "2.0.0",
"resolvedAt": "2026-01-15T10:30:00Z",
"components": [
{
"id": "store://agents/sdr-agent",
"type": "agent",
"ref": "store://agents/sdr-agent",
"resolvedVersion": "1.2.3",
"checksum": "sha256:abc123...",
"config": {},
"locked": true
},
{
"id": "store://skills/salesforce-crm",
"type": "skill",
"ref": "store://skills/salesforce-crm",
"resolvedVersion": "3.1.2",
"checksum": "sha256:def456...",
"config": {},
"locked": true
}
]
},
"status": "active"
}

Get Deployment by Team Slug

Alternative endpoint using team slug instead of deployment ID.

GET /api/manifests/deployments/:teamSlug
Authorization: Bearer <token>

Response:

{
"id": "deploy_abc123",
"teamSlug": "enterprise-sales",
"teamVersion": "2.0.0",
"status": "active",
"deployedAt": "2026-01-15T10:30:00Z",
"deployedBy": "user_123",
"lastResolvedAt": "2026-01-15T10:30:00Z",
"notes": "Initial deployment",
"manifest": { ... },
"lockFile": { ... }
}

Export

Export Manifest

Export the current deployment state as a manifest file.

GET /api/manifests/:deployId/export
Authorization: Bearer <token>

Response:

{
"manifest": {
"$schema": "https://meetloyd.com/schemas/team.manifest.json",
"name": "Enterprise Sales",
"slug": "enterprise-sales",
"version": "2.0.0",
"exportedAt": "2026-01-15T12:00:00Z",
"components": {
"agents": [
{
"ref": "store://agents/sdr-agent",
"version": "1.2.3",
"locked": true,
"localId": "sdr"
}
],
"skills": [
{
"ref": "store://skills/salesforce-crm",
"version": "3.1.2",
"locked": true
}
]
},
"orchestration": { ... }
}
}

Export Lock File

Export the lock file with resolved versions.

GET /api/manifests/deployments/:teamSlug/lockfile
Authorization: Bearer <token>

Response:

{
"manifestVersion": "2.0.0",
"resolvedAt": "2026-01-15T10:30:00Z",
"checksum": "sha256:abc123...",
"components": {
"agents": {
"store://agents/sdr-agent": {
"ref": "store://agents/sdr-agent",
"resolvedVersion": "1.2.3",
"configHash": "sha256:def456...",
"locked": true
}
},
"skills": { ... },
"avatars": { ... }
}
}

Upgrade

Upgrade Components

Upgrade specific components or all components to newer versions.

POST /api/manifests/:deployId/upgrade
Content-Type: application/json
Authorization: Bearer <token>

{
"componentIds": [
"store://agents/sdr-agent",
"store://skills/salesforce-crm"
],
"dryRun": false
}

Request Body:

FieldTypeRequiredDescription
componentIdsstring[]NoSpecific components to upgrade (all if omitted)
dryRunbooleanNoPreview changes without applying

Response:

{
"upgraded": [
"store://agents/sdr-agent",
"store://skills/salesforce-crm"
],
"lockFile": {
"manifestVersion": "2.0.0",
"resolvedAt": "2026-01-15T14:00:00Z",
"components": { ... }
}
}

Upgrade Deployment by Slug

Alternative endpoint using team slug.

POST /api/manifests/deployments/:teamSlug/upgrade
Content-Type: application/json
Authorization: Bearer <token>

{
"components": ["store://agents/sdr-agent"],
"targetVersion": "2.0.0",
"allowBreaking": false,
"dryRun": true
}

Request Body:

FieldTypeRequiredDescription
componentsstring[]NoComponents to upgrade
targetVersionstringNoTarget version constraint
allowBreakingbooleanNoAllow major version upgrades
dryRunbooleanNoPreview only

Response:

{
"success": true,
"upgrades": [
{
"ref": "store://agents/sdr-agent",
"fromVersion": "1.2.3",
"toVersion": "1.3.0",
"breaking": false,
"changelog": "Added LinkedIn integration"
}
]
}

Rollback

Rollback Component

Rollback a component to a previous version.

POST /api/manifests/:deployId/rollback
Content-Type: application/json
Authorization: Bearer <token>

{
"componentId": "store://agents/sdr-agent",
"toVersion": 2
}

Request Body:

FieldTypeRequiredDescription
componentIdstringYesComponent reference to rollback
toVersionintegerYesTarget version number

Response:

{
"success": true
}

Rollback by Component Type

Rollback using component type and ID.

POST /api/manifests/components/:componentType/:componentId/rollback
Content-Type: application/json
Authorization: Bearer <token>

{
"toDeploymentId": "deploy_abc123",
"toVersion": 2
}

Path Parameters:

ParameterDescription
componentTypeOne of: agent, skill, avatar
componentIdComponent identifier

Request Body:

FieldTypeRequiredDescription
toDeploymentIdstringNoTarget deployment ID
toVersionintegerNoTarget version number

Response:

{
"success": true,
"component": {
"id": "agent_sdr123",
"type": "agent",
"ref": "store://agents/sdr-agent"
},
"fromVersion": 3,
"toVersion": 2
}

Component References

Component references use URIs to specify sources:

Store References

store://agents/sdr-agent@^1.0.0
store://skills/salesforce-crm@~3.1.0
store://avatars/professional-emma@1.0.0

Version Specifiers:

SpecifierExampleMatches
Exact1.2.3Only 1.2.3
Caret^1.0.01.x.x (minor/patch)
Tilde~1.2.01.2.x (patch only)

Local References

local://agents/my-custom-agent
local://skills/internal-crm

For custom components in your tenant.

External References

external://heygen/avatar-emma-professional
external://elevenlabs/voice-rachel

For third-party avatar and voice providers.


Error Codes

CodeDescription
INVALID_MANIFESTManifest syntax is invalid
COMPONENT_NOT_FOUNDReferenced component doesn't exist
VERSION_NOT_SATISFIABLENo version matches constraint
DEPLOYMENT_EXISTSTeam already deployed (use force)
RESOLUTION_FAILEDCould not resolve all components
ROLLBACK_FAILEDTarget version not available
LOCKED_COMPONENTCannot upgrade locked component

Webhooks

Subscribe to manifest events:

{
"url": "https://your-app.com/webhooks",
"events": [
"manifest.deployed",
"manifest.upgraded",
"manifest.rollback",
"component.update_available"
]
}

Event Payloads:

manifest.deployed

{
"event": "manifest.deployed",
"timestamp": "2026-01-15T10:30:00Z",
"data": {
"deploymentId": "deploy_abc123",
"teamSlug": "enterprise-sales",
"teamVersion": "2.0.0",
"deployedBy": "user_123"
}
}

component.update_available

{
"event": "component.update_available",
"timestamp": "2026-01-15T10:30:00Z",
"data": {
"componentRef": "store://agents/sdr-agent",
"currentVersion": "1.2.3",
"availableVersion": "1.3.0",
"breaking": false
}
}

SDK Examples

TypeScript

import { MeetLoyd } from '@meetloyd/sdk'

const client = new MeetLoyd({ apiKey: 'YOUR_API_KEY' })

// Validate manifest
const validation = await client.manifests.validate({
manifest: myManifest
})

if (!validation.valid) {
console.error('Errors:', validation.errors)
}

// Deploy
const deployment = await client.manifests.deploy({
manifest: myManifest,
options: { notes: 'Q1 deployment' }
})

console.log('Deployed:', deployment.deployment.id)

// Upgrade
await client.manifests.upgrade(deployment.deployment.id, {
componentIds: ['store://agents/sdr-agent']
})

// Rollback
await client.manifests.rollback(deployment.deployment.id, {
componentId: 'store://agents/sdr-agent',
toVersion: 2
})

CLI

# Validate
loyd manifest validate team.manifest.json

# Resolve (dry run)
loyd manifest resolve team.manifest.json

# Deploy
loyd manifest deploy team.manifest.json --notes "Q1 deployment"

# List deployments
loyd manifest list

# Upgrade
loyd manifest upgrade deploy_abc123 --component store://agents/sdr-agent

# Rollback
loyd manifest rollback deploy_abc123 \
--component store://agents/sdr-agent \
--to-version 2

# Export
loyd manifest export deploy_abc123 > team.manifest.json

Deployment Features

Model Alias Resolution

Agent model fields accept human-friendly aliases that are automatically resolved to concrete model IDs at deploy-time:

agents:
- slug: my-agent
model: claude-sonnet-latest # Resolved to claude-sonnet-4-20250514

Available aliases: claude-opus-latest, claude-sonnet-latest, claude-haiku-latest, gpt-latest, gpt-mini-latest, gemini-latest, gemini-flash-latest, mistral-latest, deepseek-latest, llama-latest.

Aliases are resolved during deployment. The runtime executor also resolves aliases as a safety net for agents not deployed through manifests.

Authorization Grants

Agents can declare OpenFGA authorization tuples in manifests. These are provisioned at deploy-time:

agents:
- slug: crm-agent
authorization:
- resource: "crm_object_type:hubspot/contacts"
relation: editor
- resource: "git_repository:github/acme/docs"
relation: reader

Each grant creates an OpenFGA tuple: user: "agent:{id}", relation: "{relation}", object: "{resource}".

Authorization provisioning is non-fatal — if OpenFGA is unavailable, deployment continues with a warning logged.

SPIFFE Identity

Agents deployed via manifests automatically receive a SPIFFE ID (spiffe://meetloyd.com/tenant/{tenantId}/agent/{agentId}). Optional SVID configuration:

agents:
- slug: api-agent
identity:
spiffe:
audiences: ["https://partner-api.example.com"]
svidTTL: 7200

The SPIFFE ID is stored on the agent record. Identity config (audiences, TTL) is stored in orchestrationConfig.identity.

Catalog Validation

All catalog YAML manifests are validated against Zod schemas on load. Validation is warn-only — errors are logged but do not block startup or deployment. Validated schemas include:

SchemaValidates
CatalogManifestSchemaFull manifest structure
CatalogAgentSchemaAgent definitions
CatalogOrchestrationSchemaOrchestration config
CatalogInteractionRuleSchemaInteraction rules
AuthorizationGrantSchemaAuthorization grants
AgentIdentitySchemaSPIFFE identity config

Programmatic validation:

import { validateCatalogManifest } from '@meetloyd/manifests'

const result = validateCatalogManifest(rawYaml, 'my-team.yaml')
// { valid: boolean, errors: [...], warnings: [...] }

See Also