Agents

Create and configure an agent

Create the prompt templates, skills, connections and Files folders an agent uses, then publish the agent as a bundle or create it as JSON.

Write paths

MethodURLDoesAuth
POST/api/v1/agents-v2/agents/upload/Create or update an agent from a bundle ZIP, by slugKey or bearer
GET/api/v1/agents-v2/agents/{agent_id}/export/Download an agent as a bundle ZIPKey or bearer
POST/api/v1/agents-v2/agents/Create an agent from JSON; 201Key or bearer
PATCH · DELETE/api/v1/agents-v2/agents/{agent_id}/Update · delete an agent; 200 · 204Key or bearer
POST/api/v1/agents-v2/agents/{agent_id}/fork/Copy an agent, platform ones included, into the workspace; 201, no body neededKey or bearer

Platform agents are read-only: PATCH or DELETE on one returns 403 Default platform resources are read-only.; fork it instead.

Agent fields

Fields of the JSON body; agent.yaml differs as listed under agent.yaml keys.

FieldNotes
nameRequired
system_promptRequired. An empty string takes the text of prompt_template_id
prompt_template_idOptional. At run time the template's current prompt runs first, then system_prompt if it differs
model_config_idAn id from GET /api/v1/agents-v2/models/. Omitted: the platform default model
tool_namesNames from GET /api/v1/agents-v2/tools/, or tool-set names from GET /api/v1/agents-v2/tool-sets/. Sandbox tools such as execute-code are granted to every agent and are not listed
enabled_skill_slugs, enabled_skill_set_slugsSlugs from GET /api/v1/agents-v2/skills/ and GET /api/v1/agents-v2/skill-sets/
enabled_connection_ids, enabled_mcp_connection_idsIDs of connections and MCP connections in this workspace; credentials resolve for the caller at run time
enabled_file_scope{"file_ids": [...], "folder_ids": [...]} with Alo Files file and folder IDs
slugOptional; generated from name, suffixed -2, -3… when taken

Building blocks

MethodURLReturnsAuth
GET/api/v1/agents-v2/models/Models: id for model_config_id, slug for model_slug; ?enabled_only=trueKey or bearer
GET/api/v1/agents-v2/tools/Tools for tool_names: name, display_name, descriptionKey or bearer
GET/api/v1/agents-v2/tool-sets/Tool sets: name, label, tool_namesKey or bearer
GET/api/v1/agents-v2/skills/Skills; ?source, ?show_platformKey or bearer
GET/api/v1/agents-v2/skill-sets/Skill setsKey or bearer
GET/api/v1/agents-v2/prompt-templates/Prompt templates; ?show_platformKey or bearer

Prompt templates and skills

MethodURLDoesAuth
POST/api/v1/agents-v2/prompt-templates/Create; requires name, system_promptKey or bearer
GET · PATCH/api/v1/agents-v2/prompt-templates/{template_id}/Read (platform ones too) · updateKey or bearer
POST/api/v1/agents-v2/skills/Create from a SKILL.md body, no extra files; requires name, description, skill_mdKey or bearer
GET · PATCH/api/v1/agents-v2/skills/{skill_id}/Read (platform ones too) · updateKey or bearer
POST/api/v1/agents-v2/skills/upload/Create skills from a ZIPKey or bearer
GET/api/v1/agents-v2/skills/{skill_id}/export/Download one skill as a ZIPKey or bearer
POST/api/v1/agents-v2/skills/{skill_id}/upload/Replace one skill from a single-skill ZIP; its slug staysKey or bearer
DELETE/api/v1/agents-v2/prompt-templates/{template_id}/, /api/v1/agents-v2/skills/{skill_id}/Delete; 204Key or bearer
POST/api/v1/agents-v2/prompt-templates/{template_id}/fork/, /api/v1/agents-v2/skills/{skill_id}/fork/Copy a platform one into the workspace; 201Key or bearer
GET/api/v1/agents-v2/prompt-templates/store-tags/, /api/v1/agents-v2/skills/store-tags/Tags used in the template and skill catalogsKey or bearer
  • Created prompt templates and skills belong to the workspace.
  • Platform (global) ones are read-only: PATCH returns 403 Default platform resources are read-only. Copy one into the workspace instead.
  • PATCH takes only the fields you change. Sending slug renames the row (suffixed -2 when taken); agents and skill sets keep the old skill slug, and a bundle upload finds its prompt template by slug, so a rename breaks those references.

Skill sets

A skill set groups workspace skills so an agent can enable them together with enabled_skill_set_slugs.

MethodURLDoesAuth
POST/api/v1/agents-v2/skill-sets/Create from name, description, skill_slugs; 201Key or bearer
GET · PATCH · DELETE/api/v1/agents-v2/skill-sets/{skill_set_id}/Read · update the fields you send · delete (204)Key or bearer
POST/api/v1/agents-v2/skill-sets/upload/Create a set from a ZIP: each top-level folder becomes a skill; 201Key or bearer

skill_slugs must name skills in the workspace. A platform skill's slug returns 422 Unknown skills for selected space: <slug>; fork it first and use the fork's slug.

Skills from the marketplace

MethodURLDoesAuth
GET/api/v1/agents-v2/skills/marketplace/search/?query=&limit=20Search public skills: {results, total, source, query, limit}; each result has slug, github_repo, github_path, skills_sh_idKey or bearer
GET/api/v1/agents-v2/skills/marketplace/preview/?slug=&github_repo=&github_path=A skill's skill_md and files before installing; or pass skills_sh_idKey or bearer
POST/api/v1/agents-v2/skills/marketplace/install/Install one into the workspace from {slug, github_repo, github_path}; 201, a list with the new skillKey or bearer
curl -X POST "$CENTRAL_HUB_URL/api/v1/agents-v2/skills/marketplace/install/" \
  -H "X-API-Key: $ALO_API_KEY" \
  -H "X-Space-Slug: $WORKSPACE_SLUG" \
  -H "Content-Type: application/json" \
  -d '{"slug": "pdf", "github_repo": "anthropics/skills", "github_path": "pdf"}'

Bundle format

contract-analyst.zip
├── agent.yaml
├── PROMPT.md
└── skills/
    └── contract-review/
        └── SKILL.md
  • Exactly one agent.yaml; PROMPT.md and skills/ sit next to it.
  • Each skills/<slug>/SKILL.md becomes a workspace skill with that slug and is added to the agent's skills.
  • Limits: 30 MB compressed and 30 MB uncompressed per archive (400); 500 KB for agent.yaml, PROMPT.md and each SKILL.md (422).
  • Every other file in a skill folder is kept, binary files included. Only .DS_Store, Thumbs.db and anything under .git/ are dropped, without an error.

agent.yaml keys

KeyNotes
slugRequired. Upload updates the workspace agent with this slug, or creates it
nameRequired
description
model_slugA model slug from GET /api/v1/agents-v2/models/, not its ID. Omitted: the default model on create, unchanged on update
toolsTool names; the key is tools, not tool_names. Tool-set names such as alo-files are rejected
enabled_skill_slugsSkills that already exist; bundled skills are added automatically
enabled_skill_set_slugs, enabled_connection_ids, enabled_mcp_connection_ids, enabled_file_scope, tags, meta, use_ontology, use_templatesSame as the agent fields
prompt_fileDefault ./PROMPT.md, relative to agent.yaml
prompt_slug, prompt_name, prompt_descriptionThe prompt template the upload writes; default to the agent's slug, name and description
  • Any other key is ignored with a warning, such as agent.yaml has unrecognized field 'tool_names' — ignored. kind is accepted and has no effect.
  • On update, name, tools, enabled_skill_slugs and the prompt are always replaced; an omitted tools clears the agent's tools. Other omitted keys keep their current values.
  • A slug that matches a platform agent, prompt template or skill adds a warning: the workspace copy shadows it.

Minimal agent.yaml:

slug: contract-analyst
name: Contract analyst
description: Answers questions about contracts
model_slug: claude-sonnet-5
tools:
  - web-search

Publish an agent bundle

  1. Build the ZIP in the bundle format.

  2. Dry-run it with ?check=true; nothing is written:

    curl -X POST "$CENTRAL_HUB_URL/api/v1/agents-v2/agents/upload/?check=true" \
      -H "X-API-Key: $ALO_API_KEY" \
      -H "X-Space-Slug: $WORKSPACE_SLUG" \
      -F "file=@contract-analyst.zip;type=application/zip"
    {
      "check": true,
      "agent": null,
      "results": [
        {"kind": "skill", "slug": "contract-review", "id": null, "action": "would_create"},
        {"kind": "prompt_template", "slug": "contract-analyst", "id": null, "action": "would_create"},
        {"kind": "agent", "slug": "contract-analyst", "id": null, "action": "would_create"}
      ],
      "warnings": []
    }
  3. Send the same request without ?check=true. The response is 200 with check: false, the saved agent in agent, and each row's id with action created or updated.

Create an agent as JSON

  1. Find the IDs and names to reference, for example the tools:

    curl "$CENTRAL_HUB_URL/api/v1/agents-v2/tools/" \
      -H "X-API-Key: $ALO_API_KEY" \
      -H "X-Space-Slug: $WORKSPACE_SLUG"
  2. Create the agent:

    curl -X POST "$CENTRAL_HUB_URL/api/v1/agents-v2/agents/" \
      -H "X-API-Key: $ALO_API_KEY" \
      -H "X-Space-Slug: $WORKSPACE_SLUG" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "Contract analyst",
        "description": "Answers questions about contracts",
        "system_prompt": "You are a careful contract analyst. Cite the source file for every conclusion.",
        "model_config_id": 12,
        "tool_names": ["web-search", "semantic_search_tool"],
        "enabled_skill_slugs": ["contract-review"],
        "enabled_connection_ids": [42],
        "enabled_mcp_connection_ids": [7],
        "enabled_file_scope": {"file_ids": [], "folder_ids": ["<alo-files-folder-id>"]}
      }'
  3. The response is 201 with the agent: id, a slug made from name (contract-analyst), space_slug and owner_ref, the key owner's email.

  4. To change it later, send PATCH /api/v1/agents-v2/agents/{agent_id}/ with only the changed fields; DELETE the same URL removes it.

Upload a skill ZIP

Use a ZIP for a skill that ships scripts or reference files.

  1. Put each skill in its own folder: <slug>/SKILL.md plus its files. The folder name becomes the skill's slug; name and description come from the SKILL.md frontmatter.

  2. Upload it. Add ?upsert=true to update a workspace skill with the same slug:

    curl -X POST "$CENTRAL_HUB_URL/api/v1/agents-v2/skills/upload/?upsert=true" \
      -H "X-API-Key: $ALO_API_KEY" \
      -H "X-Space-Slug: $WORKSPACE_SLUG" \
      -F "file=@contract-review.zip;type=application/zip"
  3. The response is 201 with a list of the skills written.

upsertBehavior
false (default)Always creates; a slug already in the workspace lands as slug-2
trueUpdates the workspace skill with that slug in place (same id and slug); creates it if there is none

File size and type limits are the same as in a bundle.

Copy a platform skill or prompt template

  1. Find its id: platform rows have scope_visibility: "global" in GET /api/v1/agents-v2/skills/?show_platform=true or GET /api/v1/agents-v2/prompt-templates/?show_platform=true.
  2. Send POST /api/v1/agents-v2/skills/{skill_id}/fork/ or POST /api/v1/agents-v2/prompt-templates/{template_id}/fork/, with no body.
  3. The response is 201 with the workspace copy: scope_visibility: "space" and the slug with a suffix, such as skill-pharma-regulatory-c3d7e21d.

Export an agent bundle

  1. Download the ZIP:

    curl "$CENTRAL_HUB_URL/api/v1/agents-v2/agents/42/export/" \
      -H "X-API-Key: $ALO_API_KEY" \
      -H "X-Space-Slug: $WORKSPACE_SLUG" \
      -o contract-analyst.zip
  2. The export leaves out connection IDs, MCP connection IDs and the file scope; add them to agent.yaml before uploading to another workspace. Only workspace skills are embedded; platform skills stay as slugs.

Troubleshooting

ResponseCauseFix
422 {"detail": {"message": "Agent bundle validation failed", "errors": [...], "warnings": [...]}}A bundle error, such as Unknown tools: alo-files, agent.yaml is missing required field 'name' or Prompt file './PROMPT.md' referenced by agent.yaml was not foundFix each entry in errors; ?check=true reports the same errors
403 Default platform resources are read-only.The agent, skill or prompt template is a platform oneFork it: skills and prompt templates, or POST /api/v1/agents-v2/agents/{agent_id}/fork/
422 Unknown skills for selected space: <slug>A skill set names a platform skillFork the skill and use the fork's slug
404 No SKILL.md found in this archiveThe skill ZIP has no SKILL.mdPut each skill in <slug>/SKILL.md
A re-uploaded skill lands as slug-2upsert defaults to falseAdd ?upsert=true

On this page