# toolbeacon.dev Telemetry API for AI agent tools. API-only, no dashboard. ## What to Track Track any events you want—the schema is freeform. Recommended: - **User feedback**: When users report bugs or give negative feedback on tool output - **Syntax errors**: CLI parse failures, invalid arguments, malformed input - **Crashes/exceptions**: Unhandled errors with stack traces These help you understand what's broken and what users struggle with. ## Tip for Tool Authors If AI agents use your tool, document the expected feedback format in your CLI's `--help` text. Example: ``` Feedback format (for AI agents): --feedback "{ \"what\": \"description of what you tried to do\", \"issue\": \"what went wrong or was unexpected\", \"context\": \"relevant input/output that helps reproduce\" }" ``` This helps agents submit structured, actionable feedback instead of vague reports. ## Tokens You get two tokens on registration: | Token | Prefix | Use for | |-------|--------|---------| | tool_token | `toolbeacon_` | Submitting events | | admin_token | `adm_` | Viewing reports, managing tools | ## Quick Start ```bash # 1. Register (returns both tokens - save them, shown once) curl -X POST https://toolbeacon.dev/api/v1/tools \ -H "Content-Type: application/json" \ -d '{"name": "my-tool"}' # 2. Submit an event (use tool_token) curl -X POST https://toolbeacon.dev/api/v1/submit \ -H "Authorization: Bearer toolbeacon_YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"type": "syntax_error", "payload": {"input": "--badarg", "error": "unknown flag"}, "version": "1.0"}' # 3. View reports (use admin_token) curl "https://toolbeacon.dev/api/v1/reports?tool_token=toolbeacon_YOUR_TOKEN" \ -H "Authorization: Bearer adm_YOUR_TOKEN" ``` ## Submit Format ```json {"type": "...", "payload": {...}, "version": "..."} ``` All three fields required, all freeform: - **type**: Any string (`error`, `success`, `user_feedback`, whatever) - **payload**: Any JSON object - **version**: Your version string ## API Reference ### POST /api/v1/tools Register tool. No auth required (or pass admin_token to add under existing admin). ``` POST https://toolbeacon.dev/api/v1/tools Content-Type: application/json {"name": "my-tool"} ``` ### POST /api/v1/submit Submit event. Requires `tool_token`. ``` POST https://toolbeacon.dev/api/v1/submit Authorization: Bearer toolbeacon_... Content-Type: application/json {"type": "user_feedback", "payload": {"rating": "negative", "comment": "..."}, "version": "1.0"} ``` ### GET /api/v1/reports List reports. Requires `admin_token`. ``` GET https://toolbeacon.dev/api/v1/reports?tool_token=toolbeacon_... Authorization: Bearer adm_... ``` Query params: `tool_token` (required), `processed`, `limit`, `cursor` ### PATCH /api/v1/reports/{id}/processed Mark single report processed. Requires `admin_token`. ### PATCH /api/v1/reports/processed Batch mark reports processed. Requires `admin_token`. ``` PATCH https://toolbeacon.dev/api/v1/reports/processed Authorization: Bearer adm_... Content-Type: application/json {"report_ids": ["rpt_abc123", "rpt_def456"], "processed": true} ``` - `report_ids`: Array of report IDs (1-100) - `processed`: Boolean Response: ```json { "status": "success", "data": { "results": [ {"report_id": "rpt_abc123", "success": true, "error": null}, {"report_id": "rpt_def456", "success": true, "error": null} ] } } ``` Per-report errors (not found, wrong tool) return `success: false` with `error` message. ### GET /api/v1/tools List your tools. Requires `admin_token`. ### DELETE /api/v1/tools?tool_token=... Delete tool and all data. Requires `admin_token`. ### POST /api/v1/tokens?tool_token=... Create additional tool_token. Requires `admin_token`. ### DELETE /api/v1/tokens/{id} Revoke token. Requires `admin_token`. ## Python Example ```python import httpx TOOL_TOKEN = "toolbeacon_..." # from registration async def report(type: str, payload: dict): async with httpx.AsyncClient() as client: await client.post( "https://toolbeacon.dev/api/v1/submit", headers={"Authorization": f"Bearer {TOOL_TOKEN}"}, json={"type": type, "payload": payload, "version": "1.0"} ) # Recommended events await report("user_feedback", {"rating": "negative", "comment": "edited wrong file"}) await report("syntax_error", {"input": "--foo bar", "error": "unknown flag --foo"}) await report("crash", {"error": "KeyError", "stack": "...", "input_summary": "..."}) ``` ## Errors - 400: Invalid request - 401: Bad/missing token - 404: Not found - 429: Rate limited - 500: Server error