API reference
Client and worker SDKs
Install the Kiwi Distro client and worker SDKs for .NET, Java, Node.js and Python, configure them, and call the admin API from code.
Note
Kiwi Distro is currently in private preview. Interfaces and behaviour described here can change before general availability. Contact Kiwify Labs for access.
Kiwi Distro has a client SDK (call methods and use the admin API) and a worker SDK (implement methods) for .NET, Java, Node.js and Python. They follow the same wire contracts, Client protocol and Worker protocol.
Choose your language in any sample below. The choice applies to every sample on the site and is remembered in your browser.
| Language | Client SDK | Worker SDK | Requires |
|---|---|---|---|
| .NET | Kiwify.Kiwi.Distro.Client.Native |
Kiwify.Kiwi.Distro.Worker |
.NET |
| Java | kiwify-kiwi-distro-client |
kiwify-kiwi-distro-worker |
Java 17 |
| Node.js | @kiwify/kiwi-distro-client |
@kiwify/kiwi-distro-worker |
Node.js 22.18 |
| Python | kiwify-kiwi-distro-client |
kiwify-kiwi-distro-worker |
Python 3.11 |
The Java, Node.js and Python SDKs have no runtime dependencies beyond the language's standard library.
Note
The SDKs are not yet published to the public package registries. Build them from source as shown below, or ask Kiwify Labs for access.
Build and install#
Run these in the folder of the SDK you want (sdk/client/<language> or sdk/worker/<language>). In .NET, add a project reference instead.
dotnet add reference path/to/Kiwify.Kiwi.Distro.Client.Native/Kiwify.Kiwi.Distro.Client.Native.csproj
dotnet add reference path/to/Kiwify.Kiwi.Distro.Worker/Kiwify.Kiwi.Distro.Worker.csproj
mvn package # target/kiwify-kiwi-distro-client-0.1.0.jar (or ...-worker-0.1.0.jar)
npm install # dev dependencies only: TypeScript and the Node.js type definitions
npm test
pip install .
Configure#
Client and worker settings resolve from lowest to highest precedence: appsettings.json, then KIWI_-prefixed environment variables, then --key value command-line arguments, then the values you pass in code. Every setting is described in Worker and client settings.
A client needs middleware_url, client_id and client_secret. A worker needs middleware_url and auth_secret. Set middleware_ca_url to pin the middleware's CA over TLS. Treat client secrets and worker secrets like passwords: keep them in a secret store, never in source control.
Connect a client#
using Kiwify.Kiwi.Distro.Client.Native.Core;
var factory = new MiddlewareClientFactory(middlewareUrl, middlewareCaUrl);
factory.CreateAuthProviderBuilder().SetClientCredentials(clientId, clientSecret).Build();
factory.CreateHttpBuilder().Build();
KiwiClient client = KiwiClient.builder()
.middlewareUrl(middlewareUrl)
.middlewareCaUrl(middlewareCaUrl) // optional
.clientId(clientId).clientSecret(clientSecret)
.connect();
const client = await KiwiClient.connect({
middlewareUrl, middlewareCaUrl, clientId, clientSecret,
});
client = KiwiClient.connect(
middleware_url=middleware_url,
middleware_ca_url=middleware_ca_url, # optional
client_id=client_id,
client_secret=client_secret,
)
Invoking methods is covered in Invoke methods from a client, and implementing them in Write a worker.
Use the admin API#
The client SDKs expose the admin API for services, clients, workers and worker profiles, secrets, sidecar mappings, scripts and executors, feedback and groups. For example, register a service, store a secret, attach it to the service and list its workers:
using Kiwify.Kiwi.Distro.Client.Models.Request;
var services = factory.CreateServiceAdmin();
var secrets = factory.CreateSecretsAdmin();
var workers = factory.CreateWorkerAdmin();
await secrets.StoreSecretAsync(new StoreSecretRequest
{
SecretKey = "api-key", SecretType = "i", SecretValue = apiKeyValue, // "i" internal, "x" external
});
await services.CreateServiceSecretsAsync(new ServiceSecretsRequest
{
ServiceId = serviceId, Secrets = ["api-key"],
});
var list = await workers.GetAllWorkersAsync(new WorkerListRequest { ServiceId = serviceId });
client.services().create(Map.of("service_name", "billing"));
client.secrets().store("api-key", apiKeyValue); // internal
client.services().addSecrets(serviceId, List.of("api-key"));
var workers = client.workers().list(Map.of("service_id", serviceId));
await client.services.create({ service_name: "billing" });
await client.secrets.store("api-key", apiKeyValue); // internal
await client.services.addSecrets(serviceId, ["api-key"]);
const workers = await client.workers.list({ service_id: serviceId });
client.services.create({"service_name": "billing"})
client.secrets.store("api-key", api_key_value) # internal
client.services.add_secrets(service_id, ["api-key"])
workers = client.workers.list({"service_id": service_id})
To store an external secret, a reference your secrets resolver understands, pass the reference with the type x. Secrets attached to a service are delivered to its workers at registration.
Errors#
A transport, authentication or non-success HTTP failure is reported as an error: KiwiApiError (with status and body) in Node.js and Python, KiwiApiException in Java, and a failed Result in .NET. A method that ran and failed is not an error. It comes back with status: "failed" and an error message.