Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.pinata.cloud/llms.txt

Use this file to discover all available pages before exploring further.

The Agents API is the same API the dashboard uses. Everything in the UI is exposed at agents.pinata.cloud - including agent management, secrets, skills, channels, snapshots, custom domains, devices, and OpenClaw config. Full OpenAPI reference: agents.pinata.cloud/openapi (also linked from the Support → OpenAPI Docs item in the sidebar).

Base URLs

There are two surfaces, on purpose:
SurfaceHostAuthWhat it’s for
Managementagents.pinata.cloudPinata JWTCreating agents, managing secrets, browsing templates
Per-agent{agentId}.agents.pinata.cloudGateway tokenTalking to a specific agent (chat, routes, files, devices)
The same agent sub-routes (/v0/agents/{agentId}/...) are mounted on both. Use the management host when you have the workspace owner’s JWT; use the per-agent host when you only have the gateway token.

Authentication

Three credentials, used in different contexts:

Pinata JWT

Standard Pinata API key (bearerAuth in the OpenAPI spec). Used for all management routes (/v0/agents, /v0/secrets, /v0/skills, /v0/templates, etc.).
Authorization: Bearer <PINATA_JWT>
Create one in your Account → API Keys.

Gateway token

Per-agent token (gatewayToken in the OpenAPI spec) used for the agent’s own subdomain. Read it from the agent’s Danger page or GET /v0/agents/{agentId}/gateway-token. Rotate it from the same page or POST /v0/agents/{agentId}/gateway-token/rotate. Passing the gateway token:
Authorization: Bearer <GATEWAY_TOKEN>
?token=<GATEWAY_TOKEN>
Cookie: gw_token=<GATEWAY_TOKEN>
The gateway token grants full access to the agent’s container - console, files, routes, everything. Treat it like a server credential.

Git Basic auth

Used only by the Git Smart HTTP endpoints (/v0/agents/{agentId}/git/...). Sent as HTTP Basic auth - username is ignored, password is the gateway token. The Copy with Token button on the Files tab embeds this for you.

Platform JWT (for skills)

Inside an agent, the @pinata/platform skill can exchange the gateway token for a short-lived (1 hour) platform JWT. That JWT then unlocks the management-domain API (create secrets, install skills, etc.) on the agent’s behalf - so an agent can self-modify without ever seeing the user’s Pinata JWT.
# From inside the agent container:
curl -X POST \
  -H "Authorization: Bearer $OPENCLAW_GATEWAY_TOKEN" \
  https://{agentId}.agents.pinata.cloud/v0/platform/token

Quick Examples

All examples below use PINATA_JWT (from https://app.pinata.cloud) or GATEWAY_TOKEN (from the agent’s Danger page).

List your agents

curl -H "Authorization: Bearer $PINATA_JWT" \
  https://agents.pinata.cloud/v0/agents

Create an agent

curl -X POST \
  -H "Authorization: Bearer $PINATA_JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Agent",
    "description": "Personal assistant",
    "emoji": "🤖",
    "skillCids": ["@pinata/api"],
    "secretIds": ["secret-id-1"]
  }' \
  https://agents.pinata.cloud/v0/agents
Returns 201 with the created agent. Returns 403 if you’re at the agent limit.

Get agent details

curl -H "Authorization: Bearer $PINATA_JWT" \
  https://agents.pinata.cloud/v0/agents/$AGENT_ID
Response includes agent, processStatus, skills, secrets, snapshots, and portForwarding.

Restart the gateway

curl -X POST \
  -H "Authorization: Bearer $PINATA_JWT" \
  https://agents.pinata.cloud/v0/agents/$AGENT_ID/restart

Run a shell command

curl -X POST \
  -H "Authorization: Bearer $PINATA_JWT" \
  -H "Content-Type: application/json" \
  -d '{"command":"ls workspace","cwd":"/home/node/clawd"}' \
  https://agents.pinata.cloud/v0/agents/$AGENT_ID/console/exec
Returns { stdout, stderr, exitCode, command, timestamp }.

Read a file

curl -H "Authorization: Bearer $PINATA_JWT" \
  "https://agents.pinata.cloud/v0/agents/$AGENT_ID/files?path=workspace/IDENTITY.md"

Upload a file

curl -X POST \
  -H "Authorization: Bearer $PINATA_JWT" \
  -H "Content-Type: application/json" \
  -d "{\"filename\":\"report.pdf\",\"contentBase64\":\"$(base64 -w0 < report.pdf)\"}" \
  https://agents.pinata.cloud/v0/agents/$AGENT_ID/files/upload
Returns { path, filename, size }. File limit matches the read endpoint (a few MB).

Snapshot now

curl -X POST \
  -H "Authorization: Bearer $PINATA_JWT" \
  https://agents.pinata.cloud/v0/agents/$AGENT_ID/snapshots/sync

Reset to a snapshot

curl -X POST \
  -H "Authorization: Bearer $PINATA_JWT" \
  -H "Content-Type: application/json" \
  -d '{"snapshotCid":"QmXyz..."}' \
  https://agents.pinata.cloud/v0/agents/$AGENT_ID/snapshots/reset

Read the latest logs

curl -H "Authorization: Bearer $PINATA_JWT" \
  https://agents.pinata.cloud/v0/agents/$AGENT_ID/logs
Returns the last 100 lines as a single string.

Validate manifest / config

curl -X POST \
  -H "Authorization: Bearer $PINATA_JWT" \
  -H "Content-Type: application/json" \
  -d "{\"config\":$(jq -Rs . < manifest.json)}" \
  https://agents.pinata.cloud/v0/agents/$AGENT_ID/config/validate

Files

EndpointMethodNotes
/v0/agents/{agentId}/files?path=<path>GETRead any file from the container
/v0/agents/{agentId}/files/uploadPOSTUpload a base64 file into <workspace>/uploads/ (max ~few MB, 413 if too large)
/v0/agents/{agentId}/snapshotsGETLatest 10 snapshots
/v0/agents/{agentId}/snapshots/syncGET / POSTGet sync status / take a snapshot now
/v0/agents/{agentId}/snapshots/resetPOSTReset to a specific snapshot CID

Custom Domains

EndpointMethodNotes
/v0/agents/{agentId}/domainsGETList subdomains and custom domains
/v0/agents/{agentId}/domainsPOSTRegister a subdomain or custom domain
/v0/agents/{agentId}/domains/challengePOSTGet the TXT verification value for a custom domain
/v0/agents/{agentId}/domains/{domainId}PUT / DELETEUpdate port/protected or remove
/v0/agents/{agentId}/domains/{domainId}/verifyPOSTVerify ownership and provision SSL
See Routes & Domains for the full workflow.

Devices

EndpointMethodNotes
/v0/agents/{agentId}/devicesGETList pending and paired devices
/v0/agents/{agentId}/devices/{requestId}/approvePOSTApprove a specific device
/v0/agents/{agentId}/devices/approve-allPOSTBulk-approve every pending device

Streaming logs

The Logs tab streams over WebSocket on the agent’s subdomain:
wss://{agentId}.agents.pinata.cloud/v0/logs?token=<GATEWAY_TOKEN>
Each message is a JSON object: { timestamp, level, source, message }. Filter on the client by level (TRACEFATAL) and free-text on message.

Error Format

Errors return JSON with a single error field:
{ "error": "Validation failed: skills exceeds maximum of 10" }
Status codes follow HTTP semantics - 400 for validation, 401 for missing auth, 403 for plan/permission issues, 404 for missing resources, 409 for conflicts (duplicate secret name, both subdomain and customDomain provided, etc.), 413 for upload size, 500 for internal failures, 503 when an upstream (Convex, Pinata storage) is unreachable. See Errors for the full code-by-code reference.

Endpoint Quick Reference

Compact index of every endpoint, grouped by purpose. JWT = Pinata JWT, GW = gateway token (per-agent host). All paths under agents.pinata.cloud.

Agents

MethodPathAuthDescription
GET/v0/agentsJWTList your agents
POST/v0/agentsJWTCreate an agent
GET/v0/agents/{agentId}JWT / GWAgent detail (skills, secrets, snapshots, routes)
DELETE/v0/agents/{agentId}JWTDelete the agent
POST/v0/agents/{agentId}/restartJWT / GWRestart the gateway
GET/v0/agents/{agentId}/logsJWT / GWLast 100 log lines
GET/v0/agents/enginesJWTList available engines (openclaw, hermes)
GET/v0/agents/{agentId}/available-agent-versionsJWT / GWVersions you can upgrade to
POST/v0/agents/{agentId}/scripts/retryJWT / GWRe-run build then start
GET/v0/agents/{agentId}/updateJWT / GWCheck for OpenClaw updates
POST/v0/agents/{agentId}/updateJWT / GWApply an OpenClaw update

Auth

MethodPathAuthDescription
GET/v0/agents/{agentId}/gateway-tokenJWTGet the current gateway token
POST/v0/agents/{agentId}/gateway-token/rotateJWTRotate it
POST/v0/agents/{agentId}/platform/tokenGWExchange gateway token for a 1h platform JWT
GET/v0/agents/{agentId}/platform/whoamiGWAgent’s own identity

Secrets

MethodPathAuthDescription
GET/v0/secretsJWTList your secrets
POST/v0/secretsJWTCreate a secret
PUT/v0/secrets/{id}JWTUpdate value
DELETE/v0/secrets/{id}JWTDelete
POST/v0/agents/{agentId}/secretsJWT / GWAttach existing secrets to an agent
DELETE/v0/agents/{agentId}/secrets/{secretId}JWT / GWDetach a secret

Skills

MethodPathAuthDescription
GET/v0/skillsJWTList your installed skills
POST/v0/skillsJWTRegister a new skill from a folder
GET/v0/skills/{skillId}/versionsJWTList versions
POST/v0/skills/{skillId}/versionsJWTPublish a new version
DELETE/v0/skills/{skillCid}JWTRemove from library
GET/v0/clawhubJWTBrowse the community hub
GET/v0/clawhub/{slug}JWTHub skill detail
POST/v0/clawhub/{hubSkillId}/installJWTInstall a hub skill
GET/v0/agents/{agentId}/skillsJWT / GWSkills attached to this agent
POST/v0/agents/{agentId}/skillsJWT / GWAttach
DELETE/v0/agents/{agentId}/skills/{skillId}JWT / GWDetach
GET/v0/agents/{agentId}/skills/updatesJWT / GWCheck for skill updates
POST/v0/agents/{agentId}/skills/{skillId}/updateJWT / GWBump a skill on this agent

Channels

MethodPathAuthDescription
GET/v0/agents/{agentId}/channelsJWT / GWStatus of all channels
POST/v0/agents/{agentId}/channels/{channel}JWT / GWConfigure (telegram/slack/discord/whatsapp)
DELETE/v0/agents/{agentId}/channels/{channel}JWT / GWRemove

Routes & domains

MethodPathAuthDescription
GET/v0/agents/{agentId}/port-forwardingJWT / GWList path routes
PUT/v0/agents/{agentId}/port-forwardingJWT / GWReplace path routes
GET/v0/agents/{agentId}/domainsJWT / GWList domains and subdomains
POST/v0/agents/{agentId}/domainsJWT / GWRegister a subdomain or custom domain
POST/v0/agents/{agentId}/domains/challengeJWT / GWGet TXT challenge for a custom domain
PUT/v0/agents/{agentId}/domains/{domainId}JWT / GWUpdate port/protected
DELETE/v0/agents/{agentId}/domains/{domainId}JWT / GWRemove
POST/v0/agents/{agentId}/domains/{domainId}/verifyJWT / GWVerify ownership + provision SSL

Tasks

MethodPathAuthDescription
GET/v0/agents/{agentId}/tasksJWT / GWList cron jobs
POST/v0/agents/{agentId}/tasksJWT / GWCreate
GET/v0/agents/{agentId}/tasks/{jobId}JWT / GWDetail
PUT/v0/agents/{agentId}/tasks/{jobId}JWT / GWUpdate
DELETE/v0/agents/{agentId}/tasks/{jobId}JWT / GWDelete
POST/v0/agents/{agentId}/tasks/{jobId}/runJWT / GWRun now
POST/v0/agents/{agentId}/tasks/{jobId}/toggleJWT / GWEnable / disable
GET/v0/agents/{agentId}/tasks/{jobId}/runsJWT / GWRun history

Files & snapshots

MethodPathAuthDescription
GET/v0/agents/{agentId}/files?path=<path>JWT / GWRead a file from inside the container
POST/v0/agents/{agentId}/files/uploadJWT / GWUpload base64 file to <workspace>/uploads/
GET/v0/agents/{agentId}/snapshotsJWT / GWLast 10 snapshots
GET/v0/agents/{agentId}/snapshots/syncJWT / GWSync status
POST/v0/agents/{agentId}/snapshots/syncJWT / GWTrigger a snapshot now
POST/v0/agents/{agentId}/snapshots/resetJWT / GWReset to a snapshot CID

Console

MethodPathAuthDescription
POST/v0/agents/{agentId}/console/execJWT / GWRun a shell command, returns {stdout, stderr, exitCode}

Devices

MethodPathAuthDescription
GET/v0/agents/{agentId}/devicesJWT / GWList pending + paired
POST/v0/agents/{agentId}/devices/{requestId}/approveJWT / GWApprove one
POST/v0/agents/{agentId}/devices/approve-allJWT / GWApprove every pending

Config (OpenClaw runtime)

MethodPathAuthDescription
GET/v0/agents/{agentId}/configJWT / GWRead openclaw.json
PUT/v0/agents/{agentId}/configJWT / GWWrite openclaw.json (validated server-side)
POST/v0/agents/{agentId}/config/validateJWT / GWValidate openclaw.json without applying
Note config/validate validates openclaw.json (runtime config), not manifest.json. To validate a manifest, use POST /v0/templates/validate or run pinata agents templates validate.

Templates

MethodPathAuthDescription
GET/v0/templatesJWTList your templates
POST/v0/templatesJWTSubmit a template from a git repo
GET/v0/templates/{slug}JWTGet by slug
GET/v0/templates/id/{templateId}JWTGet by ID
PUT/v0/templates/{templateId}JWTUpdate / resubmit
DELETE/v0/templates/{templateId}JWTArchive
POST/v0/templates/validateJWTValidate a git repo for template submission
POST/v0/templates/branchesJWTList branches on a public repo
POST/v0/templates/refsJWTList branches + tags
GET/v0/public-templatesnonePublic marketplace listing

Git Smart HTTP

MethodPathAuthDescription
GET/v0/agents/{agentId}/git/info/refsGit Basic (GW as password)Ref advertisement
POST/v0/agents/{agentId}/git/git-upload-packGit Basic (GW as password)git clone / git pull
POST/v0/agents/{agentId}/git/git-receive-packGit Basic (GW as password)git push

OpenAPI Spec

For everything not covered here:
https://agents.pinata.cloud/openapi
The OpenAPI spec is the authoritative source - schemas, query parameters, response codes, and per-endpoint descriptions.