Skip to main content

Java SDK

The Java SDK provides typed helpers for the full pre-execution authorization flow: create a client, authorize an action, handle the three outcomes, and verify the permit before execution.

Install​

The SDK is published to Maven Central. Requires Java 17 or later.

pom.xml
<dependency>
<groupId>ai.veritrellis</groupId>
<artifactId>sdk-java</artifactId>
<version>0.1.0</version>
</dependency>
build.gradle
implementation 'ai.veritrellis:sdk-java:0.1.0'

Quick reference​

SymbolPurpose
VeritrellisClient.builder()Initialize a scoped client
client.authorize(params)Submit an action for authorization
client.verifyPermit(permit)Verify a permit JWT
client.pollPermit(requestId)Poll for a pending permit

Create a client​

Client.java
import ai.veritrellis.VeritrellisClient;

VeritrellisClient client = VeritrellisClient.builder()
.apiKey(System.getenv("VERITRELLIS_API_KEY"))
.workspaceId(System.getenv("VERITRELLIS_WORKSPACE_ID"))
.environment("sandbox") // "sandbox" | "production"
.apiUrl("https://api.veritrellis.ai")
.build();

Configuration​

OptionTypeRequiredDescription
apiKeyStringYesWorkspace API key (vt_sandbox_… or vt_prod_…)
workspaceIdStringYesYour workspace ID (ws_…)
environmentStringYes"sandbox" or "production"; must match the API key
apiUrlStringNoDefaults to https://api.veritrellis.ai

Authorize an action​

Call this before any action that requires a permit. It contacts the Veritrellis API and returns one of three outcomes.

Refund.java
import ai.veritrellis.AuthorizeParams;
import ai.veritrellis.AuthorizeResult;
import java.util.Map;

AuthorizeResult result = client.authorize(
AuthorizeParams.builder()
.actionType("issue_refund")
.resourceRef("cus_123")
.payload(Map.of(
"customer_id", "cus_123",
"amount", 75,
"currency", "EUR",
"reason", "customer request"))
.build());

Handling the three outcomes​

HandleOutcomes.java
switch (result.getDecision()) {
case "allowed":
// Permit is ready — verify it before executing
PermitClaims claims = client.verifyPermit(result.getPermit());
// Proceed with the action using verified claims
issueRefund(claims);
break;

case "pending_approval":
// Save result.getRequestId() and poll GET /v1/permits/:requestId
saveForPolling(result.getRequestId());
break;

case "denied":
// Policy blocked this request — do not execute
throw new IllegalStateException("Action denied: " + result.getReasonCode());
}
Always verify the permit

Receiving a permit from authorize is not sufficient. You must call verifyPermit before executing the action. Permits that fail verification must not unlock execution.

Request parameters​

ParameterTypeRequiredDescription
actionTypeStringYesThe canonical action type (e.g. issue_refund)
resourceRefStringYesIdentifier of the resource being acted on
payloadMap<String, Object>YesAction-specific fields; validated against shared schemas
actorRefStringNoID of the human or agent initiating the action
idempotencyKeyStringNoStable key for safe retries

Response shape​

AccessorPresent whenTypeDescription
getDecision()AlwaysString"allowed", "pending_approval", or "denied"
getRequestId()AlwaysStringUnique request identifier
getPermit()allowed onlyStringSigned ES256 permit JWT
getReasonCode()denied onlyStringMachine-readable denial reason

Verify a permit​

Verifies a permit JWT against the workspace JWKS. The client already holds the workspace ID and issuer, so it takes a single argument. Throws if the signature, issuer, audience, or expiry check fails.

Verify.java
PermitClaims claims = client.verifyPermit(result.getPermit());

The returned claims contains:

AccessorTypeDescription
getSub()StringRequest ID this permit is bound to
getWorkspaceId()StringWorkspace the permit was issued for
getActionType()StringAction type the permit authorizes
getResourceRef()StringResource the permit is scoped to
getIat()longIssued-at timestamp (Unix)
getExp()longExpiry timestamp (Unix)

Polling for a permit​

When the decision is pending_approval, poll until the request resolves:

Poll.java
String permit = client.pollPermit(result.getRequestId());
// Ready — verify before executing
PermitClaims claims = client.verifyPermit(permit);

pollPermit returns the permit once approved, and throws if the request is denied or expires.


Environment variables​

VariableRequiredDescription
VERITRELLIS_API_KEYYesAPI key from the admin app
VERITRELLIS_WORKSPACE_IDYesWorkspace ID from the admin app
Using .env files

Both the API key and workspace ID are available in the admin app under Settings > API keys. The sandbox and production environments have separate keys.


Source​

The SDK uses OkHttp internally.