{
  "schema_version": 1,
  "name": "pyai",
  "global_flags": {
    "api-key": "string",
    "base-url": "string",
    "profile": "string",
    "json": "boolean",
    "timeout": "string",
    "retries": "string",
    "dry-run": "boolean",
    "help": "boolean",
    "version": "boolean"
  },
  "short_flags": {
    "-h": "--help",
    "-v": "--version",
    "-o": "--out",
    "-f": "--file",
    "-t": "--text",
    "-p": "--profile",
    "-j": "--json"
  },
  "aliases": {
    "login": "auth login",
    "logout": "auth logout",
    "whoami": "auth status",
    "use": "profiles use",
    "say": "speak",
    "hear": "transcribe"
  },
  "commands": [
    {
      "command": "auth login",
      "description": "Sign in through the browser, or save an explicitly supplied API key",
      "flags": {
        "web": "boolean",
        "no-browser": "boolean",
        "login-timeout": "string",
        "key-stdin": "boolean"
      },
      "example": "pyai auth login --profile production"
    },
    {
      "command": "auth sandbox",
      "description": "Create a sandbox tenant and save its key in a profile"
    },
    {
      "command": "auth status",
      "description": "Inspect the active key with /v1/me"
    },
    {
      "command": "auth logout",
      "description": "Remove a saved local profile (does not revoke the key)"
    },
    {
      "command": "profiles list",
      "description": "List saved profiles without revealing keys"
    },
    {
      "command": "profiles use",
      "description": "Select the default profile",
      "args": [
        "name"
      ]
    },
    {
      "command": "models list",
      "description": "List available models"
    },
    {
      "command": "voices list",
      "description": "List voices",
      "flags": {
        "gender": "string",
        "region": "string",
        "language": "string",
        "tier": "string",
        "q": "string",
        "source": "string"
      }
    },
    {
      "command": "voices get",
      "description": "Get one voice",
      "args": [
        "id"
      ]
    },
    {
      "command": "speak",
      "description": "Synthesize text or stdin to an audio file",
      "args": [
        "text"
      ],
      "optionalArgs": true,
      "flags": {
        "text": "string",
        "text-file": "string",
        "voice": "string",
        "model": "string",
        "format": "string",
        "sample-rate": "string",
        "out": "string",
        "force": "boolean"
      },
      "example": "pyai speak \"Hello from PyAI\" -o hello.wav"
    },
    {
      "command": "transcribe",
      "description": "Transcribe a local file, or submit an audio URL as a job",
      "args": [
        "input"
      ],
      "optionalArgs": true,
      "flags": {
        "file": "string",
        "url": "string",
        "filename": "string",
        "language": "string",
        "text-only": "boolean",
        "diarize": "boolean",
        "poll": "boolean",
        "wait": "boolean",
        "wait-timeout": "string",
        "poll-interval": "string",
        "idempotency-key": "string"
      },
      "example": "pyai transcribe call.wav --text-only"
    },
    {
      "command": "dub",
      "description": "Dub a file or URL: submit, wait, and save the audio",
      "args": [
        "input"
      ],
      "optionalArgs": true,
      "flags": {
        "file": "string",
        "filename": "string",
        "url": "string",
        "from": "string",
        "to": "string",
        "out": "string",
        "force": "boolean",
        "wait-timeout": "string",
        "poll-interval": "string",
        "data": "string",
        "idempotency-key": "string"
      },
      "example": "pyai dub original.wav --from en --to hi -o dubbed.wav"
    },
    {
      "command": "clones create",
      "description": "Clone a voice from a reference audio file",
      "flags": {
        "file": "string",
        "filename": "string",
        "name": "string"
      }
    },
    {
      "command": "dub create",
      "description": "Submit a local file or URL for dubbing",
      "flags": {
        "file": "string",
        "filename": "string",
        "url": "string",
        "language": "string",
        "source-language": "string",
        "data": "string",
        "idempotency-key": "string"
      }
    },
    {
      "command": "request",
      "description": "Call a relative API route with JSON, including future endpoints",
      "args": [
        "method",
        "path"
      ],
      "flags": {
        "data": "string",
        "idempotency-key": "string",
        "out": "string",
        "force": "boolean",
        "query": "repeat"
      },
      "example": "pyai request GET /v1/me --json"
    },
    {
      "command": "schema",
      "description": "Discover CLI commands offline, or retrieve live OpenAPI",
      "args": [
        "command"
      ],
      "optionalArgs": true,
      "variadic": true,
      "flags": {
        "openapi": "boolean"
      },
      "example": "pyai schema agents create --json"
    },
    {
      "command": "recipes",
      "description": "Browse copyable workflows offline; never executes the examples",
      "args": [
        "name"
      ],
      "optionalArgs": true,
      "example": "pyai recipes speak"
    },
    {
      "command": "init",
      "description": "Create a new project with API context and request examples offline",
      "args": [
        "directory"
      ],
      "flags": {
        "template": "string"
      },
      "example": "pyai init voice-demo --template typescript"
    },
    {
      "command": "smoke",
      "description": "Check models, voices, and speech synthesis",
      "flags": {
        "tolerate-upstream": "boolean"
      }
    },
    {
      "command": "doctor",
      "description": "Diagnose key, catalogs, and a Speak to Hear round-trip"
    },
    {
      "command": "agents list",
      "description": "List managed Agent profiles.",
      "args": [],
      "flags": {
        "limit": "string",
        "cursor": "string"
      }
    },
    {
      "command": "agents get",
      "description": "Get an Agent profile.",
      "args": [
        "id"
      ],
      "flags": {}
    },
    {
      "command": "agents create",
      "description": "Create an Agent profile from JSON; name is required.",
      "args": [],
      "flags": {
        "data": "string",
        "idempotency-key": "string"
      }
    },
    {
      "command": "agents update",
      "description": "Update present Agent fields; null clears a field.",
      "args": [
        "id"
      ],
      "flags": {
        "data": "string",
        "idempotency-key": "string"
      }
    },
    {
      "command": "agents delete",
      "description": "Delete an Agent profile.",
      "args": [
        "id"
      ],
      "flags": {}
    },
    {
      "command": "jobs list",
      "description": "List transcription jobs with --limit and --cursor pagination.",
      "args": [],
      "flags": {
        "limit": "string",
        "cursor": "string"
      }
    },
    {
      "command": "jobs create",
      "description": "Create a transcription job from JSON with audio_url.",
      "args": [],
      "flags": {
        "data": "string",
        "idempotency-key": "string"
      }
    },
    {
      "command": "jobs get",
      "description": "Get transcription status and result.",
      "args": [
        "id"
      ],
      "flags": {}
    },
    {
      "command": "jobs cancel",
      "description": "Cancel a pending transcription job; completed results are retained.",
      "args": [
        "id"
      ],
      "flags": {}
    },
    {
      "command": "jobs wait",
      "description": "Wait for a transcription job to finish.",
      "args": [
        "id"
      ],
      "flags": {
        "wait-timeout": "string",
        "poll-interval": "string"
      }
    },
    {
      "command": "clones list",
      "description": "List cloned voices belonging to the current organization.",
      "args": [],
      "flags": {
        "limit": "string",
        "cursor": "string"
      }
    },
    {
      "command": "clones delete",
      "description": "Delete a cloned voice.",
      "args": [
        "id"
      ],
      "flags": {}
    },
    {
      "command": "design create",
      "description": "Generate voice candidates from a JSON prompt.",
      "args": [],
      "flags": {
        "data": "string",
        "idempotency-key": "string"
      }
    },
    {
      "command": "design get",
      "description": "Get voice design status and candidate previews.",
      "args": [
        "id"
      ],
      "flags": {}
    },
    {
      "command": "design wait",
      "description": "Wait for voice design candidates.",
      "args": [
        "id"
      ],
      "flags": {
        "wait-timeout": "string",
        "poll-interval": "string"
      }
    },
    {
      "command": "design save",
      "description": "Save a candidate using candidate_id and name.",
      "args": [
        "id"
      ],
      "flags": {
        "data": "string",
        "idempotency-key": "string"
      }
    },
    {
      "command": "cast capabilities",
      "description": "Discover currently supported Cast voices and directions.",
      "args": [],
      "flags": {}
    },
    {
      "command": "cast direct",
      "description": "Assign emotion and intensity to script text.",
      "args": [],
      "flags": {
        "data": "string",
        "idempotency-key": "string"
      }
    },
    {
      "command": "cast speech",
      "description": "Render one directed line to a WAV file.",
      "args": [],
      "flags": {
        "data": "string",
        "idempotency-key": "string",
        "out": "string",
        "force": "boolean"
      }
    },
    {
      "command": "cast render",
      "description": "Create a render with voice and script or directed lines.",
      "args": [],
      "flags": {
        "data": "string",
        "idempotency-key": "string"
      }
    },
    {
      "command": "cast get",
      "description": "Get Cast render status.",
      "args": [
        "id"
      ],
      "flags": {}
    },
    {
      "command": "cast wait",
      "description": "Wait for a Cast render to finish.",
      "args": [
        "id"
      ],
      "flags": {
        "wait-timeout": "string",
        "poll-interval": "string"
      }
    },
    {
      "command": "cast audio",
      "description": "Download completed Cast audio to a WAV file.",
      "args": [
        "id"
      ],
      "flags": {
        "out": "string",
        "force": "boolean"
      }
    },
    {
      "command": "dub get",
      "description": "Get Dub progress and output details.",
      "args": [
        "id"
      ],
      "flags": {}
    },
    {
      "command": "dub wait",
      "description": "Wait for a Dub job to finish.",
      "args": [
        "id"
      ],
      "flags": {
        "wait-timeout": "string",
        "poll-interval": "string"
      }
    },
    {
      "command": "dub audio",
      "description": "Download completed dubbed audio.",
      "args": [
        "id"
      ],
      "flags": {
        "out": "string",
        "force": "boolean"
      }
    },
    {
      "command": "dub video",
      "description": "Download a completed video-source job's dubbed video.",
      "args": [
        "id"
      ],
      "flags": {
        "out": "string",
        "force": "boolean"
      }
    },
    {
      "command": "recap list",
      "description": "List calls with Recap summaries.",
      "args": [],
      "flags": {
        "limit": "string",
        "cursor": "string"
      }
    },
    {
      "command": "recap get",
      "description": "Get a call's Recap summary.",
      "args": [
        "id"
      ],
      "flags": {}
    },
    {
      "command": "recap config",
      "description": "Read Recap configuration.",
      "args": [],
      "flags": {}
    },
    {
      "command": "recap configure",
      "description": "Update Recap configuration from JSON.",
      "args": [],
      "flags": {
        "data": "string",
        "idempotency-key": "string"
      }
    },
    {
      "command": "trace list",
      "description": "List Trace interactions.",
      "args": [],
      "flags": {
        "limit": "string",
        "cursor": "string"
      }
    },
    {
      "command": "trace get",
      "description": "Get a Trace interaction's findings and timeline.",
      "args": [
        "id"
      ],
      "flags": {}
    },
    {
      "command": "trace config",
      "description": "Read Trace configuration.",
      "args": [],
      "flags": {}
    },
    {
      "command": "trace configure",
      "description": "Update Trace configuration from JSON.",
      "args": [],
      "flags": {
        "data": "string",
        "idempotency-key": "string"
      }
    },
    {
      "command": "trace findings",
      "description": "List Trace findings.",
      "args": [],
      "flags": {}
    },
    {
      "command": "trace violations",
      "description": "List Trace violations.",
      "args": [],
      "flags": {}
    },
    {
      "command": "trace exposure",
      "description": "Get aggregate Trace exposure.",
      "args": [],
      "flags": {}
    },
    {
      "command": "tools list",
      "description": "List hosted and registered tools.",
      "args": [],
      "flags": {
        "limit": "string",
        "cursor": "string"
      }
    },
    {
      "command": "tools get",
      "description": "Get a tool definition.",
      "args": [
        "id"
      ],
      "flags": {}
    },
    {
      "command": "tools create",
      "description": "Register a tool from JSON.",
      "args": [],
      "flags": {
        "data": "string",
        "idempotency-key": "string"
      }
    },
    {
      "command": "tools update",
      "description": "Update a registered tool.",
      "args": [
        "id"
      ],
      "flags": {
        "data": "string",
        "idempotency-key": "string"
      }
    },
    {
      "command": "tools delete",
      "description": "Delete a registered tool.",
      "args": [
        "id"
      ],
      "flags": {}
    },
    {
      "command": "vocabulary get",
      "description": "Read organization Hear vocabulary and activation profiles.",
      "args": [],
      "flags": {}
    },
    {
      "command": "vocabulary set",
      "description": "Replace terms and enabled_for profiles from JSON.",
      "args": [],
      "flags": {
        "data": "string",
        "idempotency-key": "string"
      }
    },
    {
      "command": "amd calls",
      "description": "List answering-machine detection decisions.",
      "args": [],
      "flags": {
        "limit": "string",
        "cursor": "string"
      }
    },
    {
      "command": "amd get",
      "description": "Get one answering-machine detection decision.",
      "args": [
        "id"
      ],
      "flags": {}
    },
    {
      "command": "amd config",
      "description": "Read answering-machine detection configuration.",
      "args": [],
      "flags": {}
    },
    {
      "command": "amd configure",
      "description": "Configure AMD aggressiveness and webhook from JSON.",
      "args": [],
      "flags": {
        "data": "string",
        "idempotency-key": "string"
      }
    }
  ],
  "routes": [
    {
      "command": "agents list",
      "method": "GET",
      "path": "/v1/agents",
      "description": "List managed Agent profiles."
    },
    {
      "command": "agents get",
      "method": "GET",
      "path": "/v1/agents/{id}",
      "id": true,
      "description": "Get an Agent profile."
    },
    {
      "command": "agents create",
      "method": "POST",
      "path": "/v1/agents",
      "body": true,
      "description": "Create an Agent profile from JSON; name is required."
    },
    {
      "command": "agents update",
      "method": "POST",
      "path": "/v1/agents/{id}",
      "id": true,
      "body": true,
      "description": "Update present Agent fields; null clears a field."
    },
    {
      "command": "agents delete",
      "method": "DELETE",
      "path": "/v1/agents/{id}",
      "id": true,
      "description": "Delete an Agent profile."
    },
    {
      "command": "jobs list",
      "method": "GET",
      "path": "/v1/transcription/jobs",
      "description": "List transcription jobs with --limit and --cursor pagination."
    },
    {
      "command": "jobs create",
      "method": "POST",
      "path": "/v1/transcription/jobs",
      "body": true,
      "description": "Create a transcription job from JSON with audio_url."
    },
    {
      "command": "jobs get",
      "method": "GET",
      "path": "/v1/transcription/jobs/{id}",
      "id": true,
      "description": "Get transcription status and result."
    },
    {
      "command": "jobs cancel",
      "method": "DELETE",
      "path": "/v1/transcription/jobs/{id}",
      "id": true,
      "description": "Cancel a pending transcription job; completed results are retained."
    },
    {
      "command": "jobs wait",
      "method": "GET",
      "path": "/v1/transcription/jobs/{id}",
      "id": true,
      "wait": {
        "success": [
          "completed"
        ],
        "failure": [
          "failed",
          "cancelled"
        ]
      },
      "description": "Wait for a transcription job to finish."
    },
    {
      "command": "clones list",
      "method": "GET",
      "path": "/v1/voice/clones",
      "description": "List cloned voices belonging to the current organization."
    },
    {
      "command": "clones delete",
      "method": "DELETE",
      "path": "/v1/voice/clones/{id}",
      "id": true,
      "description": "Delete a cloned voice."
    },
    {
      "command": "design create",
      "method": "POST",
      "path": "/v1/voice/design",
      "body": true,
      "description": "Generate voice candidates from a JSON prompt."
    },
    {
      "command": "design get",
      "method": "GET",
      "path": "/v1/voice/design/{id}",
      "id": true,
      "description": "Get voice design status and candidate previews."
    },
    {
      "command": "design wait",
      "method": "GET",
      "path": "/v1/voice/design/{id}",
      "id": true,
      "wait": {
        "success": [
          "completed"
        ],
        "failure": [
          "failed"
        ]
      },
      "description": "Wait for voice design candidates."
    },
    {
      "command": "design save",
      "method": "POST",
      "path": "/v1/voice/design/{id}/save",
      "id": true,
      "body": true,
      "description": "Save a candidate using candidate_id and name."
    },
    {
      "command": "cast capabilities",
      "method": "GET",
      "path": "/v1/cast/capabilities",
      "description": "Discover currently supported Cast voices and directions."
    },
    {
      "command": "cast direct",
      "method": "POST",
      "path": "/v1/cast/direct",
      "body": true,
      "description": "Assign emotion and intensity to script text."
    },
    {
      "command": "cast speech",
      "method": "POST",
      "path": "/v1/cast/speech",
      "body": true,
      "binary": true,
      "description": "Render one directed line to a WAV file."
    },
    {
      "command": "cast render",
      "method": "POST",
      "path": "/v1/cast/render_jobs",
      "body": true,
      "description": "Create a render with voice and script or directed lines."
    },
    {
      "command": "cast get",
      "method": "GET",
      "path": "/v1/cast/render_jobs/{id}",
      "id": true,
      "description": "Get Cast render status."
    },
    {
      "command": "cast wait",
      "method": "GET",
      "path": "/v1/cast/render_jobs/{id}",
      "id": true,
      "wait": {
        "success": [
          "done"
        ],
        "failure": [
          "error"
        ]
      },
      "description": "Wait for a Cast render to finish."
    },
    {
      "command": "cast audio",
      "method": "GET",
      "path": "/v1/cast/render_jobs/{id}/audio",
      "id": true,
      "binary": true,
      "description": "Download completed Cast audio to a WAV file."
    },
    {
      "command": "dub get",
      "method": "GET",
      "path": "/v1/dub/jobs/{id}",
      "id": true,
      "description": "Get Dub progress and output details."
    },
    {
      "command": "dub wait",
      "method": "GET",
      "path": "/v1/dub/jobs/{id}",
      "id": true,
      "wait": {
        "success": [
          "done"
        ],
        "failure": [
          "error"
        ]
      },
      "description": "Wait for a Dub job to finish."
    },
    {
      "command": "dub audio",
      "method": "GET",
      "path": "/v1/dub/jobs/{id}/audio",
      "id": true,
      "binary": true,
      "description": "Download completed dubbed audio."
    },
    {
      "command": "dub video",
      "method": "GET",
      "path": "/v1/dub/jobs/{id}/video",
      "id": true,
      "binary": true,
      "description": "Download a completed video-source job's dubbed video."
    },
    {
      "command": "recap list",
      "method": "GET",
      "path": "/v1/recap/calls",
      "description": "List calls with Recap summaries."
    },
    {
      "command": "recap get",
      "method": "GET",
      "path": "/v1/recap/calls/{id}",
      "id": true,
      "description": "Get a call's Recap summary."
    },
    {
      "command": "recap config",
      "method": "GET",
      "path": "/v1/recap/config",
      "description": "Read Recap configuration."
    },
    {
      "command": "recap configure",
      "method": "PUT",
      "path": "/v1/recap/config",
      "body": true,
      "description": "Update Recap configuration from JSON."
    },
    {
      "command": "trace list",
      "method": "GET",
      "path": "/v1/trace/interactions",
      "description": "List Trace interactions."
    },
    {
      "command": "trace get",
      "method": "GET",
      "path": "/v1/trace/interactions/{id}",
      "id": true,
      "description": "Get a Trace interaction's findings and timeline."
    },
    {
      "command": "trace config",
      "method": "GET",
      "path": "/v1/trace/config",
      "description": "Read Trace configuration."
    },
    {
      "command": "trace configure",
      "method": "PUT",
      "path": "/v1/trace/config",
      "body": true,
      "description": "Update Trace configuration from JSON."
    },
    {
      "command": "trace findings",
      "method": "GET",
      "path": "/v1/trace/findings",
      "description": "List Trace findings."
    },
    {
      "command": "trace violations",
      "method": "GET",
      "path": "/v1/trace/violations",
      "description": "List Trace violations."
    },
    {
      "command": "trace exposure",
      "method": "GET",
      "path": "/v1/trace/exposure",
      "description": "Get aggregate Trace exposure."
    },
    {
      "command": "tools list",
      "method": "GET",
      "path": "/v1/tools",
      "description": "List hosted and registered tools."
    },
    {
      "command": "tools get",
      "method": "GET",
      "path": "/v1/tools/{id}",
      "id": true,
      "description": "Get a tool definition."
    },
    {
      "command": "tools create",
      "method": "POST",
      "path": "/v1/tools",
      "body": true,
      "description": "Register a tool from JSON."
    },
    {
      "command": "tools update",
      "method": "POST",
      "path": "/v1/tools/{id}",
      "id": true,
      "body": true,
      "description": "Update a registered tool."
    },
    {
      "command": "tools delete",
      "method": "DELETE",
      "path": "/v1/tools/{id}",
      "id": true,
      "description": "Delete a registered tool."
    },
    {
      "command": "vocabulary get",
      "method": "GET",
      "path": "/v1/hear/vocabulary",
      "description": "Read organization Hear vocabulary and activation profiles."
    },
    {
      "command": "vocabulary set",
      "method": "PUT",
      "path": "/v1/hear/vocabulary",
      "body": true,
      "description": "Replace terms and enabled_for profiles from JSON."
    },
    {
      "command": "amd calls",
      "method": "GET",
      "path": "/v1/amd/calls",
      "description": "List answering-machine detection decisions."
    },
    {
      "command": "amd get",
      "method": "GET",
      "path": "/v1/amd/calls/{id}",
      "id": true,
      "description": "Get one answering-machine detection decision."
    },
    {
      "command": "amd config",
      "method": "GET",
      "path": "/v1/amd/config",
      "description": "Read answering-machine detection configuration."
    },
    {
      "command": "amd configure",
      "method": "POST",
      "path": "/v1/amd/config",
      "body": true,
      "description": "Configure AMD aggressiveness and webhook from JSON."
    }
  ],
  "templates": [
    {
      "id": "agent",
      "description": "API context and JSON requests for coding agents",
      "files": [
        "README.md",
        "PYAI.md",
        "speech.json",
        "job.json",
        "agent.json",
        ".env.example",
        ".gitignore"
      ]
    },
    {
      "id": "typescript",
      "description": "Runnable Node.js Speak and Hear examples using @pyai/sdk",
      "files": [
        "README.md",
        "PYAI.md",
        "main.ts",
        "package.json",
        ".env.example",
        ".gitignore"
      ]
    },
    {
      "id": "python",
      "description": "Runnable Python Speak and Hear examples using pyai-sdk",
      "files": [
        "README.md",
        "PYAI.md",
        "main.py",
        ".env.example",
        ".gitignore"
      ]
    }
  ],
  "output": {
    "success": "JSON result on stdout with --json; no progress mixed in",
    "error": "JSON error on stderr with --json",
    "authorization": "Browser login emits public authorization events as NDJSON on stderr while waiting",
    "binary": "--out - streams bytes; cannot combine with --json",
    "text": "transcribe --text-only prints transcript text; cannot combine with --json"
  },
  "exit_codes": {
    "0": "success",
    "1": "API or job failure",
    "2": "arguments or local configuration",
    "3": "authentication or permission",
    "4": "network or timeout",
    "130": "interrupted"
  }
}
