Tools API Reference
Tools API Reference
Section titled “Tools API Reference”Complete documentation of /v1/tools/* endpoints for managing the tool registry.
Create or Update Tool (Upsert)
Section titled “Create or Update Tool (Upsert)”Endpoint: POST /v1/tools
Create a new tool or update an existing tool in your registry (same name + scope_id).
Request
Section titled “Request”curl -X POST https://api.onceonly.tech/v1/tools \ -H "Authorization: Bearer once_live_xxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "name": "send_email", "scope_id": "global", "url": "https://api.example.com/v1/send-email", "auth": { "type": "hmac_sha256", "secret": "your_shared_secret_key" }, "timeout_ms": 15000, "max_retries": 2, "enabled": true, "description": "Send transactional emails via SMTP service" }'Request Body
Section titled “Request Body”| Field | Type | Required | Description |
|---|---|---|---|
name | string | ✓ | Tool name (alphanumeric + _, ., :, -) |
scope_id | string | ✓ | Scope: "global" or "agent:agent_id" |
url | string | ✓ | Tool endpoint URL |
auth.type | string | ✓ | Always "hmac_sha256" |
auth.secret | string | ✓ | Shared secret (min 8 chars) |
timeout_ms | integer | - | Timeout (250-120000, default: 15000) |
max_retries | integer | - | Retry count (0-10, default: 2) |
enabled | boolean | - | Active status (default: true) |
description | string | - | Tool description (max 512 chars) |
Response
Section titled “Response”{ "name": "send_email", "scope_id": "global", "url": "https://api.example.com/v1/send-email", "timeout_ms": 15000, "max_retries": 2, "enabled": true, "description": "Send transactional emails via SMTP service", "has_secret": true, "secret_id": "sec_a1b2c3d4", "secret_mask": "***key"}List Tools
Section titled “List Tools”Endpoint: GET /v1/tools
List all tools in a scope.
Request
Section titled “Request”curl -H "Authorization: Bearer once_live_xxxxxxxxxxxxx" \ "https://api.onceonly.tech/v1/tools?scope_id=global"Query Parameters
Section titled “Query Parameters”| Parameter | Type | Description |
|---|---|---|
scope_id | string | Scope to list (default: "global") |
Response
Section titled “Response”[ { "name": "send_email", "scope_id": "global", "url": "https://api.example.com/v1/send-email", "enabled": true, "has_secret": true, "secret_id": "sec_a1b2c3d4", "secret_mask": "***key" }, { "name": "create_ticket", "scope_id": "global", "url": "https://api.example.com/v1/tickets", "enabled": true }]Get Tool
Section titled “Get Tool”Endpoint: GET /v1/tools/{name}
Get details for a specific tool.
Request
Section titled “Request”curl -H "Authorization: Bearer once_live_xxxxxxxxxxxxx" \ "https://api.onceonly.tech/v1/tools/send_email?scope_id=global"Path Parameters
Section titled “Path Parameters”| Parameter | Description |
|---|---|
name | Tool name |
Query Parameters
Section titled “Query Parameters”| Parameter | Description |
|---|---|
scope_id | Scope (default: "global") |
Response
Section titled “Response”{ "name": "send_email", "scope_id": "global", "url": "https://api.example.com/v1/send-email", "timeout_ms": 15000, "max_retries": 2, "enabled": true, "description": "Send emails", "has_secret": true, "secret_id": "sec_a1b2c3d4", "secret_mask": "***key"}To update a tool, call POST /v1/tools again with the same name + scope_id and the new fields.
Toggle Tool
Section titled “Toggle Tool”Endpoint: POST /v1/tools/{name}/toggle
Enable or disable a tool.
Request
Section titled “Request”curl -X POST https://api.onceonly.tech/v1/tools/send_email/toggle \ -H "Authorization: Bearer once_live_xxxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{"enabled": false}'Request Body
Section titled “Request Body”| Field | Type | Required |
|---|---|---|
enabled | boolean | ✓ |
Response
Section titled “Response”{ "name": "send_email", "enabled": false}Delete Tool
Section titled “Delete Tool”Endpoint: DELETE /v1/tools/{name}
Remove tool from registry.
Request
Section titled “Request”curl -X DELETE https://api.onceonly.tech/v1/tools/send_email?scope_id=global \ -H "Authorization: Bearer once_live_xxxxxxxxxxxxx"Query Parameters
Section titled “Query Parameters”| Parameter | Description |
|---|---|
scope_id | Scope (default: "global") |
Response
Section titled “Response”{ "ok": true, "deleted": "send_email", "scope_id": "global"}Error Responses
Section titled “Error Responses”401 - Missing Authorization
Section titled “401 - Missing Authorization”{ "detail": "Missing Authorization Bearer token"}403 - Invalid or Disabled API Key
Section titled “403 - Invalid or Disabled API Key”{ "detail": "Invalid API key"}403 - Forbidden
Section titled “403 - Forbidden”{ "detail": { "error": "feature_not_available", "feature": "tools_registry", "plan": "free", "required_plan": "pro" }}404 - Not Found
Section titled “404 - Not Found”{ "detail": { "error": "tool_not_found", "name": "nonexistent_tool", "scope_id": "global" }}422 - Validation Error (FastAPI/Pydantic)
Section titled “422 - Validation Error (FastAPI/Pydantic)”{ "detail": [ { "type": "missing", "loc": ["body", "name"], "msg": "Field required", "input": {} } ]}Best Practices
Section titled “Best Practices”✅ DO:
- Validate URL format before creating
- Use descriptive tool names
- Document secret handling
- Test tool endpoints before registering
- Monitor tool usage metrics
- Update stale endpoints
❌ DON’T:
- Expose secrets in logs
- Change tool URL without testing
- Delete tools in use by policies
- Create duplicate tools with different names
- Use unreliable endpoints
Examples
Section titled “Examples”Register Email Service
Section titled “Register Email Service”import osfrom onceonly import OnceOnly
def register_sendgrid(): client = OnceOnly(api_key=os.environ["ONCEONLY_API_KEY"]) return client.gov.create_tool({ "name": "sendgrid_email", "scope_id": "global", "url": "https://api.sendgrid.com/v3/mail/send", "auth": { "type": "hmac_sha256", "secret": os.environ["SENDGRID_WEBHOOK_SECRET"], }, "timeout_ms": 10000, "max_retries": 2, "description": "SendGrid email delivery", })List All Tools
Section titled “List All Tools”import osfrom onceonly import OnceOnly
def list_all_tools(): client = OnceOnly(api_key=os.environ["ONCEONLY_API_KEY"]) return client.gov.list_tools(scope_id="global")Disable Tool Temporarily
Section titled “Disable Tool Temporarily”import osfrom onceonly import OnceOnly
def disable_tool(tool_name: str): client = OnceOnly(api_key=os.environ["ONCEONLY_API_KEY"]) return client.gov.toggle_tool(tool_name, enabled=False, scope_id="global")See also: Tools Concepts