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
| Method | URL | Does | Auth |
|---|---|---|---|
POST | /api/v1/agents-v2/agents/upload/ | Create or update an agent from a bundle ZIP, by slug | Key or bearer |
GET | /api/v1/agents-v2/agents/{agent_id}/export/ | Download an agent as a bundle ZIP | Key or bearer |
POST | /api/v1/agents-v2/agents/ | Create an agent from JSON; 201 | Key or bearer |
PATCH · DELETE | /api/v1/agents-v2/agents/{agent_id}/ | Update · delete an agent; 200 · 204 | Key or bearer |
POST | /api/v1/agents-v2/agents/{agent_id}/fork/ | Copy an agent, platform ones included, into the workspace; 201, no body needed | Key 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.
| Field | Notes |
|---|---|
name | Required |
system_prompt | Required. An empty string takes the text of prompt_template_id |
prompt_template_id | Optional. At run time the template's current prompt runs first, then system_prompt if it differs |
model_config_id | An id from GET /api/v1/agents-v2/models/. Omitted: the platform default model |
tool_names | Names 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_slugs | Slugs from GET /api/v1/agents-v2/skills/ and GET /api/v1/agents-v2/skill-sets/ |
enabled_connection_ids, enabled_mcp_connection_ids | IDs 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 |
slug | Optional; generated from name, suffixed -2, -3… when taken |
Building blocks
| Method | URL | Returns | Auth |
|---|---|---|---|
GET | /api/v1/agents-v2/models/ | Models: id for model_config_id, slug for model_slug; ?enabled_only=true | Key or bearer |
GET | /api/v1/agents-v2/tools/ | Tools for tool_names: name, display_name, description | Key or bearer |
GET | /api/v1/agents-v2/tool-sets/ | Tool sets: name, label, tool_names | Key or bearer |
GET | /api/v1/agents-v2/skills/ | Skills; ?source, ?show_platform | Key or bearer |
GET | /api/v1/agents-v2/skill-sets/ | Skill sets | Key or bearer |
GET | /api/v1/agents-v2/prompt-templates/ | Prompt templates; ?show_platform | Key or bearer |
Prompt templates and skills
| Method | URL | Does | Auth |
|---|---|---|---|
POST | /api/v1/agents-v2/prompt-templates/ | Create; requires name, system_prompt | Key or bearer |
GET · PATCH | /api/v1/agents-v2/prompt-templates/{template_id}/ | Read (platform ones too) · update | Key or bearer |
POST | /api/v1/agents-v2/skills/ | Create from a SKILL.md body, no extra files; requires name, description, skill_md | Key or bearer |
GET · PATCH | /api/v1/agents-v2/skills/{skill_id}/ | Read (platform ones too) · update | Key or bearer |
POST | /api/v1/agents-v2/skills/upload/ | Create skills from a ZIP | Key or bearer |
GET | /api/v1/agents-v2/skills/{skill_id}/export/ | Download one skill as a ZIP | Key or bearer |
POST | /api/v1/agents-v2/skills/{skill_id}/upload/ | Replace one skill from a single-skill ZIP; its slug stays | Key or bearer |
DELETE | /api/v1/agents-v2/prompt-templates/{template_id}/, /api/v1/agents-v2/skills/{skill_id}/ | Delete; 204 | Key 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; 201 | Key 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 catalogs | Key or bearer |
- Created prompt templates and skills belong to the workspace.
- Platform (global) ones are read-only:
PATCHreturns403 Default platform resources are read-only.Copy one into the workspace instead. PATCHtakes only the fields you change. Sendingslugrenames the row (suffixed-2when 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.
| Method | URL | Does | Auth |
|---|---|---|---|
POST | /api/v1/agents-v2/skill-sets/ | Create from name, description, skill_slugs; 201 | Key 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; 201 | Key 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
| Method | URL | Does | Auth |
|---|---|---|---|
GET | /api/v1/agents-v2/skills/marketplace/search/?query=&limit=20 | Search public skills: {results, total, source, query, limit}; each result has slug, github_repo, github_path, skills_sh_id | Key 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_id | Key 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 skill | Key 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.mdandskills/sit next to it. - Each
skills/<slug>/SKILL.mdbecomes 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 foragent.yaml,PROMPT.mdand eachSKILL.md(422). - Every other file in a skill folder is kept, binary files included. Only
.DS_Store,Thumbs.dband anything under.git/are dropped, without an error.
agent.yaml keys
| Key | Notes |
|---|---|
slug | Required. Upload updates the workspace agent with this slug, or creates it |
name | Required |
description | |
model_slug | A model slug from GET /api/v1/agents-v2/models/, not its ID. Omitted: the default model on create, unchanged on update |
tools | Tool names; the key is tools, not tool_names. Tool-set names such as alo-files are rejected |
enabled_skill_slugs | Skills 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_templates | Same as the agent fields |
prompt_file | Default ./PROMPT.md, relative to agent.yaml |
prompt_slug, prompt_name, prompt_description | The 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.kindis accepted and has no effect. - On update,
name,tools,enabled_skill_slugsand the prompt are always replaced; an omittedtoolsclears 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-searchPublish an agent bundle
-
Build the ZIP in the bundle format.
-
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": [] } -
Send the same request without
?check=true. The response is200withcheck: false, the saved agent inagent, and each row'sidwithactioncreatedorupdated.
Create an agent as JSON
-
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" -
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>"]} }' -
The response is
201with the agent:id, aslugmade fromname(contract-analyst),space_slugandowner_ref, the key owner's email. -
To change it later, send
PATCH /api/v1/agents-v2/agents/{agent_id}/with only the changed fields;DELETEthe same URL removes it.
Upload a skill ZIP
Use a ZIP for a skill that ships scripts or reference files.
-
Put each skill in its own folder:
<slug>/SKILL.mdplus its files. The folder name becomes the skill's slug;nameanddescriptioncome from theSKILL.mdfrontmatter. -
Upload it. Add
?upsert=trueto 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" -
The response is
201with a list of the skills written.
upsert | Behavior |
|---|---|
false (default) | Always creates; a slug already in the workspace lands as slug-2 |
true | Updates 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
- Find its
id: platform rows havescope_visibility: "global"inGET /api/v1/agents-v2/skills/?show_platform=trueorGET /api/v1/agents-v2/prompt-templates/?show_platform=true. - Send
POST /api/v1/agents-v2/skills/{skill_id}/fork/orPOST /api/v1/agents-v2/prompt-templates/{template_id}/fork/, with no body. - The response is
201with the workspace copy:scope_visibility: "space"and the slug with a suffix, such asskill-pharma-regulatory-c3d7e21d.
Export an agent bundle
-
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 -
The export leaves out connection IDs, MCP connection IDs and the file scope; add them to
agent.yamlbefore uploading to another workspace. Only workspace skills are embedded; platform skills stay as slugs.
Troubleshooting
| Response | Cause | Fix |
|---|---|---|
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 found | Fix 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 one | Fork 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 skill | Fork the skill and use the fork's slug |
404 No SKILL.md found in this archive | The skill ZIP has no SKILL.md | Put each skill in <slug>/SKILL.md |
A re-uploaded skill lands as slug-2 | upsert defaults to false | Add ?upsert=true |