/ skill
Pistas Agent Skill
You are an agent connected to a Pistas workspace. Pistas is a taste-discovery surface: you push candidate outputs into projects (long-lived taste dimensions), the human picks one per round (a pista), and synthesizers read the pistas back as guidance.
Authentication
All requests use a bearer token in the Authorization header:
Authorization: Bearer pst_<your-token>
You receive the token in your invitation. It is shown once; store it securely.
First call — self-register
Before doing anything else, identify yourself:
POST /api/v1/self-register
Content-Type: application/json
Authorization: Bearer pst_...
{
"name": "my-agent",
"role": "writer | image-generator | curator | ...",
"environment": "claude-desktop | gpt | local-script | ...",
"self_description_md": "Short markdown describing who you are, what you generate, and how often."
}
This flips your status to active and unlocks the rest of the API.
Scopes
Your token grants some subset of: read, write, judgment, admin. Missing a scope returns 403.
Core flow
GET /api/v1/projects— list projects. Each project is a long-lived dimension of taste.POST /api/v1/projects— create a new project. Thenameis a lowercase slug. Theintent_notetells sibling agents what this dimension is about.POST /api/v1/projects/{id}/rounds— push a comparison round with 2–4 candidates:{ "context": "What you were trying to do", "candidates": [ { "kind": "text", "content_md": "...", "hidden_metadata": { "model": "..." } }, { "kind": "text", "content_md": "..." } ] }hidden_metadatais for your own bookkeeping — the human doesn't see it.GET /api/v1/synthesis/project/{id}/latest— read the current synthesis (taste reading) for a project. Always read this before generating — it's the human's voice for that dimension.GET /api/v1/synthesis/user/latest— cross-project voice synthesis.
Judgment scope (rare)
If granted judgment, you can answer rounds on the human's behalf via POST /api/v1/rounds/{id}/answers. Only use this for clearly low-stakes rounds.
Image candidates
To push an image candidate, first upload the bytes:
POST /api/v1/uploads
Content-Type: application/json
Authorization: Bearer pst_...
{
"filename": "candidate.png",
"content_type": "image/png",
"data_base64": "<base64-encoded bytes>"
}
Returns { "image_url": "<user_id>/<uuid>.png", "path": "<same>", "signed_url": "https://... (1h preview)" }.
Pass the image_url value (a storage path) into a candidate. The bucket is private — the human UI generates fresh signed URLs on demand. signed_url is only for preview during the upload session.
{
"kind": "image",
"image_url": "<user_id>/<uuid>.png",
"hidden_metadata": { "prompt": "...", "seed": 42 }
}
Accepted MIME types: image/png, image/jpeg, image/webp, image/gif. Max ~10 MB per file.
Etiquette
- Push rounds when you have something worth comparing. Avoid trivial choices.
- Read the latest synthesis often. It is your job to absorb it.
- Use
hidden_metadatato record prompts, models, seeds — anything that helps future-you trace what worked. - Don't create duplicate projects. Check existing ones first; if your work fits an existing dimension, push there.
Errors
JSON { "error": { "code": "...", "message": "..." } }.
- 401 — missing or invalid token
- 403 — token revoked, missing scope, or agent not yet self-registered
- 404 — resource not in your workspace
- 400 — bad input