Track a completed request
import { AgentMarginClient } from '@makinohq/agentmargin';
const meter = new AgentMarginClient({
endpoint: 'http://127.0.0.1:8787',
apiKey: process.env.AGENTMARGIN_API_KEY!, // server only
});
// response = completed result from an existing OpenAI Responses API call
await meter.trackOpenAIResponse(response, trustedCustomerId);
// completion = completed result from the Chat Completions API
await meter.trackOpenAIChatCompletion(completion, trustedCustomerId);- Only usage metadata is sent: customer ID, response ID, model, timestamp and token counts. No prompts or output text.
- Responses without usage are rejected rather than counted as free.
- The server estimates a USD microdollar cost only when a trusted matching price version exists.
- The provider response ID becomes the event ID, so retrying the same response is idempotent.
Trust the customer ID
Customer attribution must come from your application's authenticated server-side identity, never from input the browser sends. Keep the AgentMargin key and your OpenAI key out of client bundles and response JSON.
Next.js route handler
A sketch for an existing App Router app. Bring your own authentication and the official openai SDK.
const margin = new AgentMarginClient({
endpoint: process.env.AGENTMARGIN_ENDPOINT ?? 'http://127.0.0.1:8787',
apiKey: process.env.AGENTMARGIN_API_KEY!,
});
export async function POST(request: Request) {
// Resolve identity through server-side auth, not request JSON.
const customerId = await requireAuthenticatedCustomerId(request);
if (!customerId) return Response.json({ error: 'Unauthorized' }, { status: 401 });
const response = await openai.responses.create({ model, input: prompt, store: false });
let metering: 'recorded' | 'failed' = 'recorded';
try {
await margin.trackOpenAIResponse(response, customerId);
} catch {
// A real app needs a durable outbox, retries and monitoring.
metering = 'failed';
}
return Response.json({ text: response.output_text, metering });
}- An AI request can succeed while the metering call fails. That isn't durable accounting: you need a queue or outbox, retries, reconciliation and alerts before making margin claims.
- Token usage may not equal the final invoiced provider cost. Compare against provider billing and version prices by effective date.
- Apply your normal authentication, abuse protection and spending limits to the AI endpoint.
Try it without OpenAI
With npm run demo running, use the key it printed in a second terminal:
AGENTMARGIN_API_KEY='am_replace_with_demo_key' node --experimental-strip-types examples/track-synthetic-openai.tsThis posts a synthetic Responses-shaped event and a fictional $29 revenue record to the local API. No prompt, provider key or OpenAI request is involved. The cost stays unknown until a matching price version exists.