Tools can use an internal AI engine ("OpenAI Engine") to analyze content and power platform features — without ever exposing API keys in the frontend.
This is a user manual that describes:
URL:
/admin/openaiRequirements:
openai.manageIn the web UI you can:
The model dropdowns in /admin/openai are no longer hardcoded.
GET /v1/models server-sideallowed_models is configured, the dropdown is intersected with that allowlistThis means the admin model picker is based on what the current provider key can actually use, without exposing any key in the browser.
503, depending on endpoint).Note: provider keys are managed under API Keys and are never shown in plain text.
If Slack audit forwarding is enabled for OpenAI / SocialGPT request categories, audit entries now also include:
user_id, and name/email when available)error_reason when an upstream/provider request failsThis makes it easier for operators to see who triggered an AI request and why a failed request was rejected.
Users who are allowed to use Tools AI can create a personal bearer token:
/keys/mineUse it like this:
Authorization: Bearer <token>
This token works for AI feature endpoints (e.g. /api/ai/url/analyze) and is tied to your user account + permissions.
Tools now also supports other personal per-system tokens (for example provider_ircwatch or provider_mail_support_assistant) as long as they are:
is_ai=1)Important distinction:
provider_openai is the upstream provider secret used towards OpenAI and is never treated as an AI receiver tokenRegular new users are no longer allowed to use OpenAI-backed Tools features automatically just because a daily budget exists.
User flow:
/keys/mine/admin/openaiprovider_openai access right and can generate a Tools AI bearer tokenAdmin flow:
/admin/openaiEndpoint:
POST /api/ai/url/analyzePurpose:
Form data or JSON:
url (required) — URL to analyzequestion (optional) — analysis focus/questionprofile (optional) — prompt profile name (default: URL Analyzer if it exists, otherwise the engine falls back to a minimal default profile)JSON:
ok — true/falserequest_id — internal request idlatency_ms — approximate latencymodel — model usedresponse — model output (if ok)error — error message (if ok=false)To use the endpoint you need:
401 Unauthenticatedis_admin=1) — always allowedprovider_openaiIf the OpenAI provider isn't configured (missing global provider_openai API key), the endpoint typically returns 503.
Endpoint:
POST /api/ai/socialgpt/respondAuth / access rules:
tools_ai_bearer tokens still workapi_keys.is_ai=1)provider_openai)If the bearer token belongs to a user without approved OpenAI access, the endpoint returns 403.
Additive SocialGPT request fields:
client_nameclient_versionclient_platformThese fields are optional and let Tools identify which client build made the request. The response can also include an additive client object echoing the accepted metadata.
Failure-handling note:
error as normal text.Security behavior:
.env values, passwords, tokens, API keys, or other Tools internals.Related extension endpoints:
GET /api/social-media-tools/extension/validate-tokenGET /api/social-media-tools/extension/testPOST /api/social-media-tools/extension/testImportant difference:
validate-token only verifies that the supplied personal AI-capable token itself is validtest performs a real OpenAI-backed smoke test and therefore requires approved OpenAI access for non-admin usersThis lets clients distinguish "the token belongs to a real user" from "that user is actually allowed to run OpenAI requests right now".
curl -X POST "https://tools.tornevall.net/api/ai/url/analyze" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <TOKEN>" \
-d '{
"url": "https://example.com",
"question": "What is this page about?",
"profile": "URL Analyzer"
}'
Endpoint:
GET /api/social-media-tools/extension/modelsPurpose:
Response fields include:
models — array of available model optionsdefault_model — effective default model for this user/contextsource — whether the list came from live provider discovery or a configured fallbackwarning — optional fallback/discovery message