Decide what the application needs
This recipe writes a local event for one model request. It assigns an anonymous application user, a feature name and an application-generated request ID. These are your application's records; the example does not create MandAPI organization analytics or promise that arbitrary metadata appears in the dashboard.
Use this pattern when you need to understand which feature is active or investigate a failed request. For a real service, assign anonymous identifiers on the server using your existing account system. Do not accept another customer's identity directly from an untrusted browser.
Save a minimal event
Install the OpenAI Python client and set MANDAPI_API_KEY and MANDAPI_MODEL_ID. Save the following as tracked_request.py. The example uses a synthetic user and message. Running it makes one real request and writes usage-events.jsonl in the current folder.
# tracked_request.py
import json
import os
import time
import uuid
from datetime import datetime, timezone
from openai import OpenAI
request_id = uuid.uuid4().hex
started = time.monotonic()
record = {
"request_id": request_id,
"anonymous_user_id": "demo-user-a",
"feature": "support-demo",
"time": datetime.now(timezone.utc).isoformat(),
}
with OpenAI(
api_key=os.environ["MANDAPI_API_KEY"],
base_url="https://api.mandapi.com/v1",
timeout=30.0,
max_retries=0,
) as client:
try:
result = client.chat.completions.create(
model=os.environ["MANDAPI_MODEL_ID"],
messages=[{"role": "user", "content": "Say hello in Spanish."}],
)
record.update(status="ok", response_id=result.id, model=result.model)
if result.usage:
record.update(
prompt_tokens=result.usage.prompt_tokens,
completion_tokens=result.usage.completion_tokens,
)
except Exception as error:
record.update(status="error", error_type=type(error).__name__)
raise RuntimeError("MandAPI request failed: " + type(error).__name__) from None
finally:
record["duration_ms"] = round((time.monotonic() - started) * 1000)
with open("usage-events.jsonl", "a", encoding="utf-8") as log:
log.write(json.dumps(record, ensure_ascii=False) + "\n")
print("Saved local event:", request_id)The event contains status and duration even when the request fails. Token counts are included only if returned. The generated request ID is different from the model response ID, and neither should be treated as a monetary charge.
Use the record carefully
Open the JSONL file and verify that each run adds one event. Compare events using your application's request ID, anonymous user and feature. If you estimate cost, keep the rate date and billing assumptions beside the estimate. Reconcile actual credits with the MandAPI dashboard.
The example does not send customer identifiers to MandAPI. It also omits prompt bodies, responses, email addresses and API keys. Set access and retention appropriate to your service before collecting real customer activity.
Check the result
A successful call should save an ok event with a response ID and any returned usage; a failure should save an error event without inventing tokens. In a multi-worker service, replace the demonstration file with a database or logging system that supports concurrent writes. Build reports from your own events instead of assuming an unverified platform analytics endpoint exists.