API Reference
Personal Agents
Personal Agent settings, files, skills, packages, and template versions.
Related In Learn
Agentic Runtimes
Choose a Personal Agent runtime and manage versioned instructions, packages, and shared files for each agent.
Update a Personal Agent's instructions, files, skills, and npm packages.
Use a workspace API key or a Personal API Key as Authorization: Bearer YOUR_API_TOKEN. Personal keys also require X-Pickaxe-Workspace-Id. Personal Agent endpoints require workspace owner or editor access; shared-file settings require owner access.
Update a Personal Agent
Use the Agent API to change the prompt or model and select Chatbot (basic) or Personal Agent (agentic).
curl -X PATCH 'https://api.pickaxe.co/v1/studio/pickaxe/MY_AGENT' \
-H 'Authorization: Bearer YOUR_API_TOKEN' \
-H 'X-Pickaxe-Workspace-Id: YOUR_WORKSPACE_ID' \
-H 'Content-Type: application/json' \
-d '{"data":{"agenticRuntime":"agentic","prompt":"You are a helpful research assistant."}}'
Personal Agent prompt edits also update versioned AGENTS.md. Chatbot prompt edits leave saved Personal Agent files unchanged.
Update Personal Agent files
- Read
GET /runtimeand saveheadRevisionbefore editing. Download the active version if one exists. - Edit the files below and ZIP the directory's contents without an enclosing folder. These files apply to the
opencodeprovider returned byGET /runtime. - Create an upload, send the ZIP, stage, then publish. Use the saved revision as
expectedHeadRevisionfor both stage and publish. On409 runtime_conflict, reload, reconcile changes, and upload again. A newer revision cannot rebase a stale staged draft.
| File | Purpose |
|---|---|
AGENTS.md | Instructions |
opencode.json | Supported Personal Agent settings; plugins and executable hooks are unsupported |
.opencode/skills/<name>/SKILL.md | Skills |
agentic-runtime.environment.json | npm packages |
agentic-runtime.npm-lock.json | Required resolved npm v3 lock when packages are specified |
Limits: 12,000,000-byte ZIP, 25,000,000 bytes expanded, 500 entries, and 12 path levels.
Add npm packages
Use exact versions for up to 20 direct packages in agentic-runtime.environment.json:
{ "schemaVersion": 1, "packages": { "npm": { "is-number": "7.0.0" } } }
In a separate directory, create package.json with name: "pickaxe-agent-environment", version: "1.0.0", and dependencies equal to the manifest's packages.npm. Then run:
npm install --package-lock-only --lockfile-version=3 --ignore-scripts --registry=https://registry.npmjs.org
Copy the resulting package-lock.json into the Personal Agent's directory as agentic-runtime.npm-lock.json before zipping. Regenerate it when dependencies change. The API requires a matching lock; it does not resolve packages. Lifecycle scripts are disabled.
Publish the ZIP
Set PICKAXE_TOKEN locally. Replace the agent and workspace IDs, and set expectedHeadRevision to the value saved before editing.
import { createHash } from "node:crypto";
import { readFile } from "node:fs/promises";
const agentId = "MY_AGENT";
const expectedHeadRevision = 0; // Replace with headRevision saved before editing.
const root =
"https://api.pickaxe.co/v1/studio/pickaxe/" +
encodeURIComponent(agentId) +
"/runtime";
async function api(suffix, method = "GET", body) {
const response = await fetch(root + suffix, {
method,
headers: {
Authorization: "Bearer " + process.env.PICKAXE_TOKEN,
"X-Pickaxe-Workspace-Id": "YOUR_WORKSPACE_ID",
...(body ? { "Content-Type": "application/json" } : {}),
},
...(body ? { body: JSON.stringify(body) } : {}),
});
const result = await response.json();
if (!response.ok) throw new Error(result.error);
return result.data;
}
const bytes = await readFile("runtime.zip");
const intent = await api("/uploads", "POST", {
fileName: "runtime.zip",
size: bytes.length,
archiveSha256: createHash("sha256").update(bytes).digest("hex"),
});
const form = new FormData();
for (const [key, value] of Object.entries(intent.upload.fields))
form.append(key, value);
form.append(
"file",
new Blob([bytes], { type: "application/zip" }),
"runtime.zip",
);
// Presigned storage requests use the form's credentials, without the Pickaxe token.
const upload = await fetch(intent.upload.url, { method: "POST", body: form });
if (!upload.ok) throw new Error("Personal Agent ZIP upload failed");
await api("/versions/" + intent.versionId + "/stage", "POST", {
expectedHeadRevision,
});
const published = await api(
"/versions/" + intent.versionId + "/publish",
"POST",
{
expectedHeadRevision,
agenticRuntime: "agentic",
},
);
console.log(published);
Endpoints
All paths below follow https://api.pickaxe.co/v1/studio/pickaxe/<pickaxe_id>. Use an agent ID in the authenticated workspace and an ocwv- version ID belonging to that agent. Send JSON bodies with Content-Type: application/json; unknown body fields are rejected. Successful responses use {success: true, data: ...}.
GET /runtime
Read the Chatbot or Personal Agent selection, provider, active template, and headRevision. Before the first publication, headRevision is 0 and template is null.
{
"success": true,
"data": {
"pickaxeId": "MY_AGENT",
"agenticRuntime": "agentic",
"effectiveProvider": "opencode",
"headRevision": 1,
"template": {
"versionId": "ocwv-YOUR_VERSION_ID",
"version": 1,
"status": "published",
"digest": "ARCHIVE_SHA256",
"files": [
{
"path": "AGENTS.md",
"size": 100,
"sha256": "FILE_SHA256"
}
]
}
}
}
GET /runtime/settings
Owner only. Read whether identified users can share files across conversations and scheduled runs. Defaults to enabled; separate from User Memory.
{ "success": true, "data": { "sharedFilesEnabled": true } }
PATCH /runtime/settings
Owner only. Change shared files if the current value matches expectedSharedFilesEnabled; otherwise returns 409. Disabling retains saved files. Publishing and restoring leave this setting unchanged.
JSON body
sharedFilesEnabled(boolean, required): The new shared-files setting.expectedSharedFilesEnabled(boolean, required): The value read immediately before this change.
GET /runtime/versions
List published versions, newest first. Returns an array in data.
Query parameters
skip(integer, optional): Number of versions to skip, 0 or greater. Defaults to0.limit(integer, optional): Page size from 1 to 100. Defaults to50.
POST /runtime/uploads
Returns data.versionId and data.upload. POST every upload.fields value, then the ZIP as a file form part, to upload.url without a Pickaxe token. The URL lasts five minutes; stage within 24 hours.
JSON body
fileName(string, required): Filename ending in .zip, from 1 to 200 characters.size(integer, required): Exact archive size in bytes, from 1 to 12,000,000.archiveSha256(string, required): 64-character hexadecimal SHA-256 of the uploaded bytes.
GET /runtime/versions/<version_id>
Read metadata and the file list for a published version or your own upload or staged version.
GET /runtime/versions/<version_id>/download
Returns data.url (valid for five minutes) and data.digest (archive SHA-256). Verify the downloaded bytes before extracting. Available for staged and published versions.
POST /runtime/versions/<version_id>/stage
Validate the uploaded ZIP and return staged metadata. Does not activate it. Validation failure leaves the active version unchanged.
JSON body
expectedHeadRevision(integer, required): The headRevision saved before editing, used for both stage and publish. Must be 0 or greater.
POST /runtime/versions/<version_id>/publish
Activate a staged version and its AGENTS.md instructions. Existing sessions use it on their next activity. Use the returned data.versionId, which can differ from the staged ID. Retrying an active publication creates no additional version.
JSON body
expectedHeadRevision(integer, required): The headRevision saved before editing, used for both stage and publish. Must be 0 or greater.agenticRuntime("basic" | "agentic", optional): Also select Chatbot (basic) or Personal Agent (agentic). Omission preserves the current selection; null is invalid.
POST /runtime/versions/<version_id>/restore
Republish an earlier version with its original package lock. Returns the active version metadata. Preserves history and saved files; restoring the active version creates no additional version.
JSON body
expectedHeadRevision(integer, required): Current headRevision from GET /runtime, 0 or greater.agenticRuntime("basic" | "agentic", optional): Also select Chatbot (basic) or Personal Agent (agentic). Omission preserves the current selection; null is invalid.
