KintsugiKintsugi
SDKs

Java SDK

Official Java SDK. com.trykintsugi:kintsugi-tax-java-sdk is published on Maven Central and generated from the same OpenAPI spec that produces this API reference, so it stays in step with the API.

JDK 11 or later. Requests and models are immutable builders and responses are typed objects, so an invalid request fails at compile time rather than in production.

Installation

implementation 'com.trykintsugi:kintsugi-tax-java-sdk:0.15.3'

Maven Central lists the current version.

Authentication

The API authenticates with an API key header. Create a key in the Kintsugi app (see Creating and managing API keys), pass it once to the builder, and every call that accepts it is authenticated:

package hello.world;

import com.kintsugi.taxplatform.SDK;
import com.kintsugi.taxplatform.models.components.Security;
import com.kintsugi.taxplatform.models.operations.GetCustomerByIdV1CustomersCustomerIdGetResponse;

public class Application {

    public static void main(String[] args) throws Exception {

        SDK sdk = SDK.builder()
                .security(Security.builder()
                    .apiKeyHeader(System.getenv().getOrDefault("KINTSUGI_API_KEY", ""))
                    .build())
            .build();

        GetCustomerByIdV1CustomersCustomerIdGetResponse res = sdk.customers().getById()
                .customerId("cust_abc123")
                .call();

        if (res.customerRead().isPresent()) {
            System.out.println(res.customerRead().get());
        }
    }
}

Bodies come back as Optional, so an absent body is something the compiler makes you handle rather than a null waiting to happen.

A handful of operations take credentials per call rather than per client. The code sample on each API reference page shows a .security(...) step where that applies, using an operation specific type such as SearchV1AddressValidationSearchPostSecurity.

Making a request

Request bodies are component builders, passed with .request(...). Required fields are enforced at build time and enums are generated types, so an invalid request will not compile:

CustomerCreate req = CustomerCreate.builder()
        .name("Jane Smith")
        .email("jane.smith@example.com")
        .externalId("cust_002")
        .street1("456 Elm St")
        .city("Metropolis")
        .state("NY")
        .postalCode("10001")
        .country(CountryCodeEnum.US)
        .status(StatusEnum.ACTIVE)
        .build();

CreateCustomerV1CustomersPostResponse res = sdk.customers().create()
        .request(req)
        .call();

For the exact call on any endpoint, including its builder type, arguments and the type it returns, open that endpoint in the API reference and select the Java tab.

Error handling

Every SDK exception inherits from SDKError, which exposes message(), code(), headers, body(), bodyAsString() and rawResponse(). Catch it, then narrow to the operation's typed errors:

try {
    GetCustomerByIdV1CustomersCustomerIdGetResponse res = sdk.customers().getById()
            .customerId("cust_abc123")
            .call();

    res.customerRead().ifPresent(System.out::println);

} catch (SDKError ex) {
    System.out.println(ex.code() + " " + ex.bodyAsString());

    if (ex instanceof ErrorResponse) {
        ((ErrorResponse) ex).data()
            .ifPresent(payload -> System.out.println(payload.detail()));
    }
} catch (UncheckedIOException ex) {
    // Connection failure, timeout, and other I/O errors
}

Each method's error table is in the SDK's docs. Error handling covers what the API returns and when a retry is worthwhile.

Overriding the server URL

SDK sdk = SDK.builder()
        .serverURL("https://api.trykintsugi.com")
        .security(Security.builder()
            .apiKeyHeader(System.getenv().getOrDefault("KINTSUGI_API_KEY", ""))
            .build())
    .build();

Available resources

AddressValidation        search, suggest
Customers                get, create, getById, update, getByExternalId,
                         createTransaction
Customers.Transactions   getByCustomerId
Exemptions               get, create, getById, uploadCertificate, getAttachments
Filings                  get, getById, getByRegistrationId
Nexus                    getPhysical, createPhysical, updatePhysical,
                         deletePhysical, get
Products                 getProductsV1ProductsGet, createProductV1ProductsPost,
                         getProductCategoriesV1ProductsCategoriesGet,
                         getById, update
Registrations            get, create, getById, update, deregister
TaxEstimation            estimate
Transactions             get, create, getByExternalId, update, getById,
                         getByFilingId, updateCreditNote
Transactions.CreditNotes create