> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cognisafe.uk/llms.txt
> Use this file to discover all available pages before exploring further.

# Java SDK

> Install and configure the Cognisafe Java SDK.

## Installation

<CodeGroup>
  ```xml Maven (pom.xml) theme={null}
  <dependency>
    <groupId>uk.cognisafe</groupId>
    <artifactId>cognisafe-sdk</artifactId>
    <version>1.0.0</version>
  </dependency>
  ```

  ```groovy Gradle (build.gradle) theme={null}
  implementation 'uk.cognisafe:cognisafe-sdk:1.0.0'
  ```

  ```kotlin Gradle Kotlin DSL (build.gradle.kts) theme={null}
  implementation("uk.cognisafe:cognisafe-sdk:1.0.0")
  ```
</CodeGroup>

Requires Java 11 or higher.

## Configuration

Configure the SDK once at application startup using the builder pattern:

```java theme={null}
import uk.cognisafe.Cognisafe;
import uk.cognisafe.CognisafeConfig;

Cognisafe.configure(
    CognisafeConfig.builder()
        .apiKey("csk_your_key_here")   // or reads COGNISAFE_API_KEY
        .projectId("my-app")           // or reads COGNISAFE_PROJECT_ID
        .proxyUrl("http://localhost:8080")  // default; omit for cloud
        .apiUrl("http://localhost:8000")    // default; omit for cloud
        .build()
);
```

### Configuration options

| Option      | Type     | Required | Default                 | Description                              |
| ----------- | -------- | -------- | ----------------------- | ---------------------------------------- |
| `apiKey`    | `String` | Yes\*    | `COGNISAFE_API_KEY`     | Your project API key (`csk_...`)         |
| `projectId` | `String` | Yes\*    | `COGNISAFE_PROJECT_ID`  | Project identifier for grouping requests |
| `proxyUrl`  | `String` | No       | `http://localhost:8080` | Cognisafe Go proxy URL                   |
| `apiUrl`    | `String` | No       | `http://localhost:8000` | Cognisafe FastAPI backend URL            |

\* Required if the corresponding environment variable is not set.

<Note>
  The SDK is thread-safe. Call `Cognisafe.configure()` once at startup (e.g., in your Spring `@Configuration` class or `main()` method) — it initialises a shared singleton. Do not call `configure()` per-request.
</Note>

## Patching the OpenAI Java client

```java theme={null}
import uk.cognisafe.Cognisafe;
import uk.cognisafe.CognisafeConfig;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;

Cognisafe.configure(
    CognisafeConfig.builder()
        .apiKey("csk_your_key_here")
        .projectId("my-app")
        .build()
);

// The SDK provides a factory method that returns a pre-configured client
OpenAIClient client = Cognisafe.openAIClient();

var response = client.chat().completions().create(
    ChatCompletionCreateParams.builder()
        .model(ChatModel.GPT_4O)
        .addUserMessage("Hello from Java!")
        .build()
);

System.out.println(response.choices().get(0).message().content());
```

`Cognisafe.openAIClient()` returns a standard `OpenAIClient` with the `baseUrl` pre-configured to point at the Cognisafe proxy. You can also configure your own client by setting the base URL manually:

```java theme={null}
OpenAIClient client = OpenAIOkHttpClient.builder()
    .baseUrl(Cognisafe.getProxyUrl())
    .apiKey("your-openai-api-key")
    .build();
```

## The `@CognisafeTrace` annotation (Spring Boot)

For Spring Boot applications, use the `@CognisafeTrace` annotation on any method that calls an LLM. The SDK uses Spring AOP to intercept the call and log the inputs and outputs:

```java theme={null}
import uk.cognisafe.annotation.CognisafeTrace;
import org.springframework.stereotype.Service;

@Service
public class LlmService {

    @CognisafeTrace(model = "gpt-4o")
    public String summarise(String text) {
        // your LLM call — HTTP, custom client, etc.
        return callMyInternalModel(text);
    }
}
```

The annotation captures:

* Method arguments (serialised to JSON)
* Return value (serialised to JSON)
* Execution time (latency)

Results are shipped to `/internal/log` in a background thread — the annotated method is not blocked.

<Note>
  `@CognisafeTrace` requires the `cognisafe-sdk-spring` module. Add it alongside the core SDK:

  ```xml theme={null}
  <dependency>
    <groupId>uk.cognisafe</groupId>
    <artifactId>cognisafe-sdk-spring</artifactId>
    <version>1.0.0</version>
  </dependency>
  ```
</Note>

## Non-Spring usage (manual trace)

Without Spring AOP, wrap calls manually using `Cognisafe.trace()`:

```java theme={null}
import uk.cognisafe.Cognisafe;
import java.util.concurrent.Callable;

String result = Cognisafe.trace(
    () -> callMyInternalModel(prompt),
    "my-model",   // model name tag
    prompt        // input to record
);
```
