Java SDK
Install the Java SDK, build a client, see every method with a Java sample, and verify records offline.
Java
com.invoance:invoance on Maven Central.
Java 17 or later. Synchronous; the only runtime dependency is Jackson.
// Gradle
dependencies {
implementation 'com.invoance:invoance:0.2.0'
}
// Maven
// <dependency>
// <groupId>com.invoance</groupId>
// <artifactId>invoance</artifactId>
// <version>0.2.0</version>
// </dependency>
| apiKey | The API key. Falls back to INVOANCE_API_KEY. |
|---|---|
| baseUrl | API host. Falls back to INVOANCE_BASE_URL, then https://api.invoance.com. |
| apiVersion | Path prefix put before every request path. Default v1. |
| timeout | Per-request timeout as a Duration. Default 30 seconds; past it the call throws TimeoutException. |
| idempotencyKey | Default Idempotency-Key header for every mutating request; a per-call key wins. |
| extraHeaders / header(name, value) | Headers merged into every request. |
| Retries | None. Each request is sent once; on TimeoutException or NetworkException, retry it yourself with the same Idempotency-Key. |
import com.invoance.ClientConfig;
import com.invoance.InvoanceClient;
import com.invoance.model.ValidationResult;
import java.time.Duration;
public class Main {
public static void main(String[] args) {
// Reads INVOANCE_API_KEY and INVOANCE_BASE_URL from the environment.
InvoanceClient client = new InvoanceClient();
// Or pass options.
InvoanceClient configured = new InvoanceClient(
ClientConfig.builder()
.apiKey("invoance_live_...")
.baseUrl("https://api.invoance.com")
.timeout(Duration.ofSeconds(60))
.build());
// GET /v1/me checks no scope, so any live key passes. Never throws.
ValidationResult result = client.validate();
System.out.println(result.isValid() + " " + result.getReason());
}
}
Every endpoint with a Java sample, by resource. Open a row for the sample; the link opens the endpoint card with its fields, response and errors.
POST/v1/events
import com.invoance.InvoanceClient;
import com.invoance.model.IngestEventResponse;
import com.invoance.param.IngestEventParams;
import java.util.Map;
public class Main {
public static void main(String[] args) {
// Reads INVOANCE_API_KEY from the environment.
InvoanceClient client = new InvoanceClient();
IngestEventResponse result = client.events().ingest(
IngestEventParams.builder()
.eventType("policy.approval")
.eventTime("2026-09-22T08:14:07Z")
.payload(Map.of(
"policy_id", "pol_8472",
"approved_by", "risk_committee",
"decision", "approved"))
.idempotencyKey("policy-approval-pol_8472")
.build());
System.out.println(result.eventId + " " + result.ingestedAt);
}
}
GET/v1/events
import com.invoance.InvoanceClient;
import com.invoance.model.EventListItem;
import com.invoance.model.ListEventsResponse;
import com.invoance.param.ListEventsParams;
public class Main {
public static void main(String[] args) {
// Reads INVOANCE_API_KEY from the environment.
InvoanceClient client = new InvoanceClient();
ListEventsResponse page = client.events().list(
ListEventsParams.builder()
.page(1)
.limit(50)
.eventType("policy.approval")
.build());
System.out.println(page.total + " " + page.hasMore);
for (EventListItem event : page.events) {
System.out.println(event.eventId + " " + event.ingestedAt + " " + event.payloadHash);
}
}
}
GET/v1/events/{event_id}
import com.invoance.InvoanceClient;
import com.invoance.model.ComplianceEvent;
public class Main {
public static void main(String[] args) {
// Reads INVOANCE_API_KEY from the environment.
InvoanceClient client = new InvoanceClient();
ComplianceEvent event = client.events().get("7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4");
System.out.println(event.eventType + " " + event.ingestedAt);
System.out.println(event.payloadHash + " " + event.eventHash + " " + event.requestHash);
System.out.println(event.payload);
}
}
POST/v1/events/{event_id}/verify
import com.invoance.InvoanceClient;
import com.invoance.model.VerifyEventResponse;
import com.invoance.param.VerifyEventParams;
import java.util.Map;
public class Main {
public static void main(String[] args) {
// Reads INVOANCE_API_KEY from the environment.
InvoanceClient client = new InvoanceClient();
VerifyEventResponse result = client.events().verify(
"7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4",
VerifyEventParams.ofPayload(Map.of(
"policy_id", "pol_8472",
"approved_by", "risk_committee",
"decision", "approved")));
System.out.println(result.matchResult + " " + result.matchedField);
System.out.println(result.anchoredHash + " " + result.submittedHash + " " + result.anchoredAt);
}
}
POST/v1/document/anchor
import com.invoance.InvoanceClient;
import com.invoance.model.AnchorDocumentResponse;
import com.invoance.param.AnchorDocumentParams;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.MessageDigest;
import java.util.HexFormat;
import java.util.Map;
public class Main {
public static void main(String[] args) throws Exception {
byte[] file = Files.readAllBytes(Path.of("./INV-2026-0917.pdf"));
String documentHash = HexFormat.of().formatHex(
MessageDigest.getInstance("SHA-256").digest(file));
// Reads INVOANCE_API_KEY from the environment.
InvoanceClient client = new InvoanceClient();
AnchorDocumentResponse result = client.documents().anchor(
AnchorDocumentParams.builder()
.documentHash(documentHash)
.documentRef("INV-2026-0917.pdf")
.eventType("invoice.issued")
.metadata(Map.of(
"invoice_number", "INV-2026-0917",
"amount", 5230,
"currency", "USD"))
.idempotencyKey("anchor-" + documentHash)
.build());
System.out.println(result.eventId + " " + result.status);
}
}
GET/v1/document
import com.invoance.InvoanceClient;
import com.invoance.model.DocumentListItem;
import com.invoance.model.ListDocumentsResponse;
import com.invoance.param.ListDocumentsParams;
public class Main {
public static void main(String[] args) {
// Reads INVOANCE_API_KEY from the environment.
InvoanceClient client = new InvoanceClient();
ListDocumentsResponse page = client.documents().list(
ListDocumentsParams.builder()
.limit(25)
.dateFrom("2026-09-01T00:00:00Z")
.build());
System.out.println(page.total + " " + page.hasMore);
for (DocumentListItem d : page.documents) {
System.out.println(d.eventId + " " + d.documentRef + " " + d.hasOriginal);
}
}
}
GET/v1/document/{event_id}
import com.invoance.InvoanceClient;
import com.invoance.model.DocumentEvent;
public class Main {
public static void main(String[] args) {
// Reads INVOANCE_API_KEY from the environment.
InvoanceClient client = new InvoanceClient();
DocumentEvent doc = client.documents().get("7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4");
System.out.println(doc.documentHash + " " + doc.hasOriginal + " " + doc.createdAt);
if (doc.organization != null) {
System.out.println(doc.organization.issuerName + " " + doc.organization.domainVerified);
}
}
}
GET/v1/document/{event_id}/original
import com.invoance.InvoanceClient;
import java.nio.file.Files;
import java.nio.file.Path;
public class Main {
public static void main(String[] args) throws Exception {
// Reads INVOANCE_API_KEY from the environment.
InvoanceClient client = new InvoanceClient();
byte[] data = client.documents().getOriginal("7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4");
Files.write(Path.of("./INV-2026-0917.pdf"), data);
System.out.println(data.length);
}
}
POST/v1/document/{event_id}/verify
import com.invoance.InvoanceClient;
import com.invoance.model.VerifyDocumentResponse;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.MessageDigest;
import java.util.HexFormat;
public class Main {
public static void main(String[] args) throws Exception {
byte[] file = Files.readAllBytes(Path.of("./INV-2026-0917.pdf"));
String documentHash = HexFormat.of().formatHex(
MessageDigest.getInstance("SHA-256").digest(file));
// Reads INVOANCE_API_KEY from the environment.
InvoanceClient client = new InvoanceClient();
VerifyDocumentResponse result = client.documents().verify(
"7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4", documentHash);
System.out.println(result.matchResult + " " + result.anchoredHash + " " + result.anchoredAt);
}
}
POST/v1/ai/attestations
import com.invoance.InvoanceClient;
import com.invoance.model.IngestAttestationResponse;
import com.invoance.param.IngestAttestationParams;
public class Main {
public static void main(String[] args) {
// Reads INVOANCE_API_KEY from the environment.
InvoanceClient client = new InvoanceClient();
IngestAttestationResponse result = client.attestations().ingest(
IngestAttestationParams.builder()
.type("output")
.input("Summarize the termination clause in contract CT-8472.")
.output("Either party may terminate with 30 days written notice. Early termination fees do not apply after month 12.")
.modelProvider("openai")
.modelName("gpt-4.1")
.modelVersion("2026-04-14")
.userId("u_4821")
.sessionId("sess_9f3a")
.subjectField("department", "legal")
.idempotencyKey("ct-8472-summary-1")
.build());
System.out.println(result.attestationId + " " + result.payloadHash);
}
}
GET/v1/ai/attestations
import com.invoance.InvoanceClient;
import com.invoance.model.ListAttestationsResponse;
import com.invoance.param.ListAttestationsParams;
public class Main {
public static void main(String[] args) {
// Reads INVOANCE_API_KEY from the environment.
InvoanceClient client = new InvoanceClient();
ListAttestationsResponse page = client.attestations().list(
ListAttestationsParams.builder()
.limit(50)
.attestationType("output")
.modelProvider("openai")
.build());
System.out.println(page.total + " " + page.hasMore + " " + page.attestations.size());
}
}
GET/v1/ai/attestations/{attestation_id}
import com.invoance.InvoanceClient;
import com.invoance.model.AiAttestation;
public class Main {
public static void main(String[] args) {
// Reads INVOANCE_API_KEY from the environment.
InvoanceClient client = new InvoanceClient();
AiAttestation att = client.attestations().get("7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4");
System.out.println(att.attestationHash + " " + att.signatureAlg + " " + att.publicKey);
}
}
GET/v1/ai/attestations/{attestation_id}/raw
import com.invoance.InvoanceClient;
import java.util.Map;
public class Main {
public static void main(String[] args) {
// Reads INVOANCE_API_KEY from the environment.
InvoanceClient client = new InvoanceClient();
Map<String, Object> raw = client.attestations().getRaw("7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4");
System.out.println(raw.get("type") + " " + raw.get("context"));
}
}
POST/v1/ai/attestations/{attestation_id}/verify
import com.invoance.InvoanceClient;
import com.invoance.model.VerifyAttestationResponse;
public class Main {
public static void main(String[] args) {
// Reads INVOANCE_API_KEY from the environment.
InvoanceClient client = new InvoanceClient();
VerifyAttestationResponse result = client.attestations().verify(
"7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4",
"c4efe15781214a84046ad7e0592977c634a5cf45f4c1e06160daf760a295a8df");
System.out.println(result.matchResult + " " + result.matchedField);
}
}
POST/v1/traces
import com.invoance.InvoanceClient;
import com.invoance.model.CreateTraceResponse;
import com.invoance.param.CreateTraceParams;
import java.util.Map;
public class Main {
public static void main(String[] args) {
// Reads INVOANCE_API_KEY from the environment.
InvoanceClient client = new InvoanceClient();
CreateTraceResponse trace = client.traces().create(
CreateTraceParams.builder()
.label("Invoice batch 2026-09")
.metadata(Map.of("batch_id", "b_4471", "region", "eu-west"))
.build());
System.out.println(trace.traceId + " " + trace.status);
}
}
POST/v1/traces/{trace_id}/seal
import com.invoance.InvoanceClient;
import com.invoance.model.SealTraceResponse;
public class Main {
public static void main(String[] args) {
// Reads INVOANCE_API_KEY from the environment.
InvoanceClient client = new InvoanceClient();
SealTraceResponse sealed = client.traces().seal("7c1e4b52-9a0f-4d2e-b6f3-2f8a61c0d9e4");
System.out.println(sealed.status + " " + sealed.message);
}
}
POST/v1/audit/events
import com.invoance.InvoanceClient;
import com.invoance.param.IngestAuditEventParams;
import java.util.List;
import java.util.Map;
public class Main {
public static void main(String[] args) {
// Reads INVOANCE_API_KEY from the environment.
InvoanceClient client = new InvoanceClient();
Map<String, Object> result = client.audit().events().ingest(
IngestAuditEventParams.builder()
.organizationId("org_8472")
.action("user.signed_in")
.occurredAt("2026-09-22T08:14:07Z")
.actor(Map.<String, Object>of("type", "user", "id", "u_4821", "name", "Ada Lovelace"))
.targets(List.of(Map.<String, Object>of("type", "workspace", "id", "ws_17")))
.context(Map.<String, Object>of("location", "203.0.113.10", "user_agent", "Mozilla/5.0"))
.metadata(Map.<String, Object>of("method", "sso", "mfa", true))
.idempotencyKey("signin-u_4821-2026-09-22T08:14:07Z")
.build());
System.out.println(result.get("event_id") + " " + result.get("ingested_at"));
}
}
POST/v1/audit/orgs
import com.invoance.InvoanceClient;
import com.invoance.param.CreateAuditOrgParams;
import java.util.Map;
public class Main {
public static void main(String[] args) {
// Reads INVOANCE_API_KEY from the environment.
InvoanceClient client = new InvoanceClient();
Map<String, Object> org = client.audit().orgs().create(
CreateAuditOrgParams.builder()
.organizationId("org_8472")
.name("Acme Robotics")
.build());
System.out.println(org.get("id") + " " + org.get("retention_days"));
}
}
GET/v1/me
import com.invoance.InvoanceClient;
import java.util.Map;
public class Main {
public static void main(String[] args) {
// Reads INVOANCE_API_KEY from the environment.
InvoanceClient client = new InvoanceClient();
Map<String, Object> me = client.me();
System.out.println(me.get("organization"));
System.out.println(me.get("limits"));
}
}
Two checks run without trusting the server: attestations().verifySignature fetches the record and checks its Ed25519 signature over signed_payload; AuditVerify.verifyAuditEvent rebuilds the invoance.audit/1 bytes of an audit event, given as a Map of its wire fields, and checks its signature. Pass the hex key from GET /keys/{domain} as the second argument to pin it instead of the key on the row.
import com.invoance.AuditVerify;
import com.invoance.InvoanceClient;
import com.invoance.model.AuditEvent;
import com.invoance.model.AuditVerifyResult;
import com.invoance.model.SignatureVerificationResult;
import java.util.LinkedHashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
InvoanceClient client = new InvoanceClient();
// AI attestation: Ed25519 over signed_payload, checked locally.
SignatureVerificationResult sig =
client.attestations().verifySignature("a1d4f8c2-7b3e-4e9a-b5c6-0d2e8f4a7c19");
System.out.println(sig.isValid());
// Audit event: canonical bytes rebuilt locally, signature checked
// against a pinned key (the public_key from GET /keys/{domain}, base64url decoded to hex).
String pinnedHexKey = "d4443bd9d30ef4c2e0e5db03467e3c5c740358482c1a1e30cdb27a2e02a38176";
AuditEvent evt = client.audit().events().get("aevt_01J8F3KQ2R7VWX9YB4ND6MCZAH");
Map<String, Object> event = new LinkedHashMap<>();
event.put("id", evt.id);
event.put("org_id", evt.orgId);
event.put("seq", evt.seq);
event.put("occurred_at", evt.occurredAt);
event.put("ingested_at", evt.ingestedAt);
event.put("action", evt.action);
event.put("actor", evt.actor);
event.put("targets", evt.targets);
event.put("context", evt.context);
event.put("metadata", evt.metadata);
event.put("payload_hash", evt.payloadHash);
event.put("signature", evt.signature);
event.put("signing_public_key", evt.signingPublicKey);
AuditVerifyResult result = AuditVerify.verifyAuditEvent(event, pinnedHexKey);
System.out.println(result.isValid() + " " + result.getReason() + " " + result.getKeySource()); // pinned
}
}