Claude Code http hook: send paid Sume call records to an audit log

An http hook POSTs hook input to a URL, with headers from allowed environment variables only. Log Sume tool names and idempotency keys with a tiny receiver.

3 min readSume
All posts

Yes, Claude Code can send every Sume tool call to your own logging service with an http hook. The hooks reference shows the shape: a url, optional headers such as Authorization: Bearer $MY_TOKEN, an allowedEnvVars list that names which environment variables may be expanded into headers, and a timeout. Tool event hooks receive tool_name, tool_input and tool_use_id, which is enough for a spend audit.

A shared audit log helps a team that connects several people to Sume with one API key. Sume's docs say write and paid tools carry an idempotency_key, so the log can show which key went with which tool call.

Fields that matter

From the hooks reference.

http hook fields (read 2026-10-08)
FieldRoleNote
urlWhere the hook input goesUse https for anything off your machine
headersRequest headersMay reference environment variables
allowedEnvVarsWhich variables may be expandedList every variable you want expanded
timeoutSeconds before the hook is canceledDefault 600 for http
matcher (on the group)Which tool names fire itUse the Sume tool prefix

A receiver you can run

This standard-library receiver prints the tool name and the idempotency key of each POSTed call and answers 200. It assumes the body is the JSON hook input; confirm that against your first request before you build on it.

import json
from http.server import BaseHTTPRequestHandler, HTTPServer


class Audit(BaseHTTPRequestHandler):
    def do_POST(self):
        size = int(self.headers.get("Content-Length", "0"))
        data = json.loads(self.rfile.read(size) or b"{}")
        args = data.get("tool_input") or {}
        print(data.get("tool_name"), args.get("idempotency_key"), flush=True)
        self.send_response(200)
        self.end_headers()


HTTPServer(("127.0.0.1", 8099), Audit).serve_forever()

Steps

Start the receiver, add a PreToolUse or PostToolUse hook with type: http and url: http://127.0.0.1:8099, set the matcher to the Sume prefix, and run one harmless read such as balance_get. You should see its name in the receiver output. Then widen to the paid tools. Put real traffic behind https and a token passed through allowedEnvVars.

  • Never put the Sume API key in the audit log; log the tool name and idempotency key only.
  • Use PostToolUse if you want to log what ran, PreToolUse if you want to log what was attempted.
  • Check claude --debug-file hooks.log if nothing arrives.

What to record and what to leave out

A useful audit row has four fields: when the call was attempted, which tool, which idempotency key, and who ran it. The hook input also includes a session id and the working directory, so you can tie a row to a session and a project. Leave out the bearer token, any signed download URLs that appear in tool results, and the full prompt text unless you have a reason to keep it, since prompts for image and video work can contain private material.

Add a retention rule at the same time. A log of paid calls is useful for a month of reconciliation against Sume's job list, and a liability after that if it also holds prompts.

What Sume does not do

Sume keeps its own job records, which you read with jobs_list. It does not forward calls to your log, and the hook is on your side of the connection. A log built this way records what Claude Code attempted, not what Sume billed.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume