Java SDK
The Java SDK has two parts:
- Tracing (
com.ants.platform.tracingandcom.ants.platform.otel). Built on OpenTelemetry. It exports spans tohttps://<your-ants-host>/api/public/otel/v1/tracesand maps them to traces and observations. - API client (
com.ants.platform.client.AntsPlatformClient). A typed client for the public REST API: traces, observations, sessions, scores, prompts, datasets and more.
| Value | |
|---|---|
| Maven coordinates | ai.agenticants:ants-platform-java |
| Current version | 0.3.0 |
| Java version | 17 or later |
| Auth | Project public key (pk-ap-...) and secret key (sk-ap-...) |
Create a key pair under Project Settings > API Keys. See API Keys.
Install
The SDK brings in the OpenTelemetry API, SDK and OTLP exporter, Jackson and OkHttp.
Configure
The tracing setup reads these environment variables. Values set on the builder take precedence.
| Variable | Purpose |
|---|---|
ANTS_PLATFORM_PUBLIC_KEY | Project public key |
ANTS_PLATFORM_SECRET_KEY | Project secret key |
ANTS_PLATFORM_BASE_URL | Your ANTS Platform URL, for example https://<your-ants-host> |
ANTS_PLATFORM_TRACING_ENVIRONMENT | Environment label on every span, for example production |
ANTS_PLATFORM_RELEASE | Release label on every span |
The Java SDK reads ANTS_PLATFORM_BASE_URL, not ANTS_PLATFORM_HOST (the
Python SDK variable). If neither the variable nor .baseUrl(...) is set, the
SDK sends to https://api.agenticants.ai. Set it explicitly for any other
deployment.
Trace an agent
Configure tracing once at startup
configure registers a global OpenTelemetry instance with the ANTS Platform span
processor. .agent(name, displayName) tags every span with a stable agent ID so
the agent appears in the AI Agent Center. Keep the agent name stable. The
display name can change later.
Create observations
Observations started inside observe nest under it automatically. The span ends
when the function returns. If it throws, the error is recorded on the
observation (level ERROR) and rethrown.
Flush before the process exits
Use AntsPlatformOtel.flush() to send buffered spans without shutting down, for
example at the end of a request in a long-running service.
Cost is calculated by ANTS Platform from the model name and token usage. Pass
.cost(Map.of(...)) on a generation to send your own cost instead.
Tracing API
Entry points (Ants)
| Method | What it does |
|---|---|
startObservation(name) / startObservation(name, type) | Starts an observation under the current active span. Call .end() yourself. |
startObservation(name, type, parent) | Starts an observation under an explicit parent. |
startGeneration(name) / startGeneration(name, parent) | Starts a generation. Call .end() yourself. |
observe(name, type, fn) | Runs fn with a new active observation and returns its result. Ends the span, records errors. |
observeGeneration(name, fn) | Same as observe for a generation. |
startActiveObservation(name, type, consumer) / startActiveGeneration(name, consumer) | Same as observe without a return value. |
updateActiveTrace(attrs) | Sets trace attributes on the current active span. |
currentObservation() | Returns the current active observation, or null. |
Observation types (ObservationType)
SPAN, GENERATION, AGENT, TOOL, RETRIEVER, CHAIN, EMBEDDING,
EVALUATOR, GUARDRAIL, EVENT. GENERATION and EMBEDDING accept model,
usage and cost fields.
Observation methods
| Method | Applies to |
|---|---|
input(obj), output(obj), metadata(obj) | All |
level(text) with DEBUG, DEFAULT, WARNING or ERROR; statusMessage(text); version(text) | All |
recordError(throwable) | All |
updateTrace(TraceAttributes) | All |
startChild(name, type), startChildGeneration(name) | All |
end(), end(Instant) | All |
traceId(), id() | All |
model(name), modelParameters(map) | Generations and embeddings |
usage(input, output), usage(input, output, total), usage(map) | Generations and embeddings |
cost(map), completionStartTime(instant), prompt(name, version) | Generations and embeddings |
Trace attributes (TraceAttributes.builder())
name, userId, sessionId, version, release, input, output,
metadata, tags, isPublic, environment.
Span processor options (AntsPlatformOtel.options())
publicKey, secretKey, baseUrl, environment, release,
agent(name) or agent(name, displayName), flushIntervalMillis,
timeoutMillis.
Use your own OpenTelemetry setup
AntsPlatformSpanProcessor is a standard OpenTelemetry SpanProcessor. If your
application already builds its own SdkTracerProvider, add the processor to it
instead of calling AntsPlatformOtel.configure:
Spans from other OpenTelemetry instrumentation registered on the same provider
are exported too. You can also export from any OpenTelemetry SDK without this
library: send OTLP/HTTP to https://<your-ants-host>/api/public/otel with an
Authorization: Basic <base64(pk:sk)> header. See
Sending Data In.
REST API client
The client exposes one accessor per API resource: trace(), observations(),
sessions(), score(), scoreV2(), scoreConfigs(), prompts(),
promptVersion(), datasets(), datasetItems(), datasetRunItems(),
comments(), annotationQueues(), metrics(), models(), media(),
ingestion(), projects(), organizations(), scim() and health(). Builder
options: url, credentials, timeout (seconds) and httpClient (a custom
OkHttp client).
Use the tracing API above to send traces. The low-level ingestion() endpoint
is available for custom pipelines.
Guardrails
The SDK includes com.ants.platform.guardrails.AntsGuardrailsClient and
provider wrappers that check prompts and responses against an agent's guardrail
policy. See AI Guardrails.
Each check accepts up to 1,000,000 characters of text; longer text is checked in
overlapping windows (see Long text).
The Java SDK does not ask for the WARNING result, so a check that warns
returns PASS. The warning is still recorded in
AI Violations.
Tool governance
From 0.3.0, com.ants.platform.guardrails.tools.AntsToolGuard checks an agent's
tool calls against its tool permissions
before the tool runs. It is on by default when agentId is set, and changes
nothing until the agent has an approved tool.
guardTool(name, arguments, supplier)runs the supplier only when the call is allowed and, when needed, approved.- When the agent's AI Guardrails policy is Block or Redact, a call that breaks
a rule throws
ToolNotAllowedException. Under Audit Only, or with no policy, the call runs and the violation is reported in the background. - A call that needs approval creates an approval request and waits for the
decision. A denial, an expiry or no answer within
approvalTimeoutthrowsToolApprovalDeniedException. - Tool calls of a suspended
agent throw
ToolNotAllowedException, even when the agent has no policy.
| Method | Use |
|---|---|
guardTool(...), enforceTool(name, arguments), enforceTools(...) | Check calls and throw when they are blocked or not approved |
checkTool(name), checkTools(...) | Check calls and return a ToolCheckResult; never throw |
runAs(idToken, supplier) / setUserToken(idToken) | Verify the OIDC ID token of the user the agent acts for, for group-limited tools. The user is kept per thread. |
checkDefinitions(...) / enforceDefinitions(...) | Compare MCP tool definitions with the pinned ones |
requestApproval(...), approvalStatus(...), awaitApproval(...) | Handle approvals yourself |
| Builder option | Default | Description |
|---|---|---|
enforceTools(boolean) | true | Pass false to turn tool governance off |
failMode(FailMode) | OPEN | CLOSED blocks tool calls when the tool settings were never loaded |
approvalTimeout(Duration) | 5 minutes | How long to wait for an approval |
approvalPollInterval(Duration) | 2 seconds | How often to ask for the decision |
The tool settings are refreshed about every minute, and the last copy is kept if a refresh fails. Rate limits are counted in the process. Deny patterns use RE2 syntax, as on the platform.
Troubleshooting
401on export. Check the key pair and that both keys belong to the project you expect. The SDK logs a warning at startup when a key is missing.- No traces from a short-lived process. Call
AntsPlatformOtel.shutdown()before exit so buffered spans are sent. - Traces go to the wrong host. Set
ANTS_PLATFORM_BASE_URLor.baseUrl(...). The SDK does not readANTS_PLATFORM_HOST. - Agent missing from the AI Agent Center. Set
.agent(...)on the span processor options.