Skip to main content
The Invocations panel in the tool manager is your primary debugging surface. Every call (live + test) lands there within 1-2 seconds with full request, response, latency, signature, and error code if any.

”My tool isn’t firing during calls”

The AI never chose to call it. Checks in order:
1

Is the tool active?

In the manager, the row should show a green dot and Active. If it says Disabled, hit Enable.
2

Is the agent-level toggle on?

In Agent Studio → Tools, the Custom HTTP Tools card should show Active (not Configured). If it says Configured, the master switch is off — toggle it.
3

Is the description aligned with what the caller said?

The AI uses the description to decide when to call. If your description says “use this for billing routing” and the caller asked about returns, the AI won’t call it.Fix: make the description broader, or test with a more on-topic prompt.
4

Place a test call and watch the panel

Even on a misfire, the panel won’t show anything (because no call happened). That’s expected.

”I see HTTP_TOOL_TIMEOUT in the log”

Your endpoint took longer than 10 seconds.
  • Click the invocation row → see the full request URL.
  • Try the URL yourself with curl (no signing needed for the timing test): time curl -X POST https://your-url -d '{}'.
  • If your URL is slow, profile your code. Common culprits: cold-start serverless functions, slow DB queries, sync calls to external APIs.

”I see HTTP_TOOL_CONNECTION_FAILED”

DNS failed, TCP refused, or TLS handshake failed.
  • Verify your endpoint resolves: dig your-hostname.example.com.
  • Verify TLS works: curl -v https://your-url 2>&1 | grep "SSL connection".
  • Check certificate expiration: openssl s_client -connect your-host:443 < /dev/null | openssl x509 -noout -dates.
  • Confirm public reachability from outside your network: curl https://your-url from a different network than your dev box.

”I see HTTP_TOOL_URL_BLOCKED”

SSRF guard fired at invocation time (DNS rebinding pattern). Run dig +short your-hostname.example.com from your terminal. If any returned IP is in the blocked ranges, that’s why we rejected the call. If your hostname genuinely resolves to a public IP but we still block, open a ticket with the resolved IP — we’ll investigate.

”My signature verification keeps failing”

The most common signature-failure causes, in order:
1

You're hashing the parsed body, not the raw bytes.

Frameworks like Express, Flask, FastAPI parse JSON and discard the original bytes by default. You need to capture the raw request body before parsing.
  • Express: express.json({ verify: (req, _, buf) => { req.rawBody = buf.toString() } })
  • Flask: request.get_data() returns the raw bytes.
  • FastAPI: await request.body() returns the raw bytes.
  • Go: io.ReadAll(r.Body) once, then re-parse the bytes.
2

You're using the wrong signing secret.

Did you rotate the secret recently? The old one is dead the moment you click Rotate. Pull the latest from your environment and restart.
3

Your server clock is drifting.

We tolerate up to 60 seconds of future skew and 5 minutes of past skew. Anything beyond rejects. Sync via NTP.
4

You're using `==` instead of constant-time compare.

== works most of the time but is timing-attack-vulnerable AND occasionally fails on encoded vs raw forms. Always use timingSafeEqual / hmac.compare_digest / hash_equals / hmac.Equal.
5

Copy as curl in the dashboard and replay locally.

The Test panel’s “Copy as curl” produces a complete curl command including the signed headers. Run it from your terminal against your endpoint. If that succeeds, your live setup is fine and the issue is in some intermediate proxy / WAF / CDN.

”I see HTTP_TOOL_CUSTOMER_ERROR”

Your endpoint returned 4xx or 5xx. Click the invocation row to see the response body preview.
StatusLikely cause
401Your Bearer token check failed. Did the token in the tool config match what your server expects?
403Your server is rejecting the request even with valid auth. App-level firewall?
404Your URL path is wrong. The dashboard shows the exact URL we POSTed to.
422Your server doesn’t like the body shape. Maybe a required field is missing on your side.
500Unhandled exception. Check your error logs around the invocation timestamp.
502/503/504Upstream is down. If you’re behind a CDN, the CDN is upstream of you.

”My endpoint never receives the request”

If the dashboard shows a successful invocation but your server logs are empty:
  • Are you sure you’re looking at the right server? Check the URL in the invocation matches your real endpoint.
  • Is there an in-front-of layer (Cloudflare, AWS WAF, Nginx) intercepting before your app sees it? Check its access logs.
  • Are you filtering POST requests in your access logger? Some default configs log GET only.
If the dashboard shows HTTP_TOOL_CONNECTION_FAILED and your server logs are empty — you can’t connect; see the earlier section.

”I get HTTP_TOOL_RATE_LIMITED unexpectedly”

You spent the bucket faster than refill. Common causes:
  • Tight inner loop in the AI’s flow. If your description leads the AI to call the tool every conversational turn, you’ll burn through 30/min on one tool fast. Tighten the description so the AI calls it only when it has new info to look up.
  • Test fires bleeding into production. They shouldn’t — the test bucket is separate. If you see test-fire codes in your production invocations, tell us.
  • You genuinely need more. Open a ticket; we lift caps per-tenant when justified.

”I see HTTP_TOOL_INVALID_ARGS”

The LLM passed args that don’t match your parameters_schema. The AI usually corrects itself, but if you see this code repeating:
  • Your schema is too strict (required fields the AI can’t always provide).
  • Your description doesn’t tell the AI what shape to pass.
Fix: relax the schema (mark borderline fields optional) AND tighten the description (“Pass query as the caller’s exact words.”).

”My response body shows up garbled in the dashboard but works for the AI”

The dashboard preview is obfuscated — provider names (vapi, twilio, asterisk, etc.) are replaced with voice to keep the UI provider-clean. The AI gets the verbatim body. If you want the dashboard preview to read cleanly, don’t put provider names in your response body. The AI doesn’t need them.

When to file a support ticket

If everything above doesn’t pin down the issue, send us:
  • Your tenant ID.
  • The invocation_id from a failing row (UUID).
  • A one-line “what I expected vs what happened.”
  • Your endpoint URL (we’ll never share it).
support@getsmartalex.com. We aim for same-business-day on tool-related tickets.

Back to: HTTP Tools overview

Top-level overview and links to every section.