Developers · Integration examples
Copy, paste, govern.
Examples for common clients and frameworks. Any framework works if its model client lets you set a base URL and headers. Examples use reserved example domains.
Python · OpenAI SDK
A complete tool-calling loop. The only IntSen-specific lines are the base URL, token and headers.
from openai import OpenAIimport ulid client = OpenAI( base_url="https://gateway.intsen.example/openai/v1", api_key=get_intsen_token(), # OAuth client-credentials token for fleet-advisor-prod default_headers={ "x-intsen-registration-id": "field-service-assistant-prod", "x-intsen-agent-id": "field-service/fleet-service-advisor", },) def handle_user_message(conversation_id: str, user_id: str, messages: list) -> str: turn_headers = { "x-intsen-task-id": str(ulid.new()), # one id per user message, reused for every call in the turn "x-intsen-conversation-id": conversation_id, "x-intsen-user-id": user_id, # IntSen stores only a hash } while True: response = client.chat.completions.create( model="gpt-5.4-mini", messages=messages, tools=TOOLS, extra_headers=turn_headers) message = response.choices[0].message if not message.tool_calls: return message.content messages.append(message) messages.extend(run_tools(message.tool_calls)) # your tools, unchangedTypeScript · OpenAI SDK
Default headers on the client, turn headers per request.
import OpenAI from "openai";import { ulid } from "ulid"; const client = new OpenAI({ baseURL: "https://gateway.intsen.example/openai/v1", apiKey: await getIntsenToken(), // OAuth client-credentials token defaultHeaders: { "x-intsen-registration-id": "field-service-assistant-prod", "x-intsen-agent-id": "field-service/fleet-service-advisor", },}); // One task id per user messageconst turnHeaders = { "x-intsen-task-id": ulid(), "x-intsen-conversation-id": conversationId };const response = await client.chat.completions.create( { model: "gpt-5.4-mini", messages, tools }, { headers: turnHeaders },);LangChain / LangGraph
Set the base URL and headers on the chat model.
from langchain_openai import ChatOpenAIimport ulid def model_for_turn(conversation_id: str) -> ChatOpenAI: # A client per turn keeps the task id simple; reuse it for every call in the turn. return ChatOpenAI( model="gpt-5.4-mini", base_url="https://gateway.intsen.example/openai/v1", api_key=get_intsen_token(), default_headers={ "x-intsen-registration-id": "field-service-assistant-prod", "x-intsen-agent-id": "field-service/fleet-service-advisor", "x-intsen-task-id": str(ulid.new()), "x-intsen-conversation-id": conversation_id, }, )OpenAI Agents SDK
Point the SDK's default client at the gateway.
from openai import AsyncOpenAIfrom agents import set_default_openai_client set_default_openai_client(AsyncOpenAI( base_url="https://gateway.intsen.example/openai/v1", api_key=get_intsen_token(), default_headers={ "x-intsen-registration-id": "field-service-assistant-prod", "x-intsen-agent-id": "field-service/fleet-service-advisor", },))# Add x-intsen-task-id per user message using your framework's per-request# header option, or create a client per turn as in the LangChain example.Sub-agents
Reuse the parent's task id so the sub-agent's calls and cost appear inside the parent's turn.
# Parent agent: pass its task id to the sub-agentresult = await research_agent.run(question, task_id=turn_headers["x-intsen-task-id"]) # Sub-agent: reuse the parent's task id on its own model callsheaders = {"x-intsen-task-id": task_id, "x-intsen-agent-id": "field-service/parts-researcher"}Error handling
Refusals come back with a stable code in an OpenAI-compatible error body.
from openai import APIStatusError try: response = client.chat.completions.create( model="gpt-5.4-mini", messages=messages, extra_headers=turn_headers)except APIStatusError as err: code = (err.body or {}).get("error", {}).get("code") if code == "task_budget_exceeded": return "This request needs more steps than allowed. Please narrow it down." if code in ("model_not_allowed", "provider_not_allowed"): raise # configuration problem: check the Registration's models raiseGolden tests in CI
Run scripted scenarios from your pipeline. The adapter is a few lines that call your agent.
intsen eval run --agent field-service/fleet-service-advisor --dataset smoke \ --version $COMMIT --adapter "python tests/run_case.py" --junit out/evals.xmlGolden test adapter
A minimal adapter shape. The intsen package adds the headers for you.
# tests/run_case.py — called once per golden scenario by `intsen eval run`import sys, jsonfrom my_agent import handle_user_message case = json.load(sys.stdin) # scenario inputanswer = handle_user_message(case["conversation_id"], "ci", case["messages"])print(json.dumps({"answer": answer}))Need help with your framework?
Book a technical walkthrough and we'll work through your agent's setup with your engineers.