/ 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

  1. GET /api/v1/projects — list projects. Each project is a long-lived dimension of taste.
  2. POST /api/v1/projects — create a new project. The name is a lowercase slug. The intent_note tells sibling agents what this dimension is about.
  3. 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_metadata is for your own bookkeeping — the human doesn't see it.
  4. 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.
  5. 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

Errors

JSON { "error": { "code": "...", "message": "..." } }.