---
title: "Integrations & Billing in the SDK"
canonical: https://trickest.com/docs/developer-tools/sdk/integrations-billing
description: "Manage private image registries and understand SDK billing compatibility."
---

# Integrations & Billing in the SDK

Examples use an authenticated server-side `client: TrickestClient`.

## `client.integrations`

Docker registry integrations let workflows pull private tool images.

| Method                   | Description                                                                                        |
| ------------------------ | -------------------------------------------------------------------------------------------------- |
| `list(options?)`         | Async generator of `DockerRegistry` records                                                        |
| `get(id, options?)`      | Registry details                                                                                   |
| `create(data, options?)` | The payload accepts `name`, `url`, `username`, and `password`; see compatibility limit below |
| `delete(id, options?)`   | Remove an integration                                                                              |

<Warning>
  `create()` omits the `type` discriminator required by the current API. Its
  declared payload alone cannot create an integration against that route. Use
  `client.http.post()` with the complete API payload below.
</Warning>

This example creates a basic registry integration. Supply `registryUsername` and `registryPassword` as strings from your server's secret store.

```ts
import type { DockerRegistry } from "@trickest/sdk";

const payload: {
  type: "basic";
  name: string;
  url: string;
  username: string;
  password: string;
} = {
  type: "basic",
  name: "Private tools",
  url: "https://registry.example.com",
  username: registryUsername,
  password: registryPassword,
};
const registry = await client.http.post<DockerRegistry>(
  "/api/integrations",
  payload,
);
console.log(registry.id, registry.name);
```

The other API variants are `type: 'dockerhub'` with `name`, `username`, and `password`, and `type: 'github'` with `name`, `username`, and `token`. Keep these credentials server-side. The exported `CreateDockerRegistryPayload` describes the underlying registry representation (`vault` and `spec`), not this web API request body.

## `client.billing`

Billing reads the token's current vault. The SDK requires a positional `vaultId` and sends it as `vault_id`, but the current API resolves the vault from authentication. Passing a different ID does not switch billing scope.

| Method               | Declared result             | Compatibility                                                                                                      |
| --------------------------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `getStatus(vaultId, options?)`          | `BillingStatus`             | Returns customer data; the declared required status fields are not all guaranteed by the current customer contract |
| `getUsage(vaultId, options?)`           | `Usage`                     | Calls the traffic endpoint, which reports outbound bytes rather than the declared credit breakdown                 |
| `listCharges(vaultId, options?)`        | Async generator of `Charge` | Same scope limit                                                                                                   |
| `listPaymentMethods(vaultId, options?)` | `PaymentMethod[]`           | Current API returns a paginated envelope, not the declared array                                                   |

`getStatus()` and `getUsage()` return unvalidated API bodies. Do not assume that fields such as `is_active`, `total_credits`, or `breakdown` exist because the type declarations require them.

For payment methods, read the envelope directly. This fetches one page; use the response's pagination fields when you need further pages.

```ts
import type { PaginatedResponse, PaymentMethod } from "@trickest/sdk";

const page = await client.http.get<PaginatedResponse<PaymentMethod>>(
  "/api/billing/payment-methods?page=1&page_size=20",
);
console.log(page.results.length, page.next);
```

The HTTP generic declares the expected response shape; it does not validate responses at runtime.

Billing has a separate authorization path. A billing 401 does not establish that the same token is invalid for every other platform API.

**Types:** `BillingStatus`, `Usage`, `UsageBreakdown`, `Charge`, `PaymentMethod`

<Info>
  **CLI:** [Integrations &
  Billing](/docs/developer-tools/cli/integrations-billing).
</Info>

---
_Markdown source of https://trickest.com/docs/developer-tools/sdk/integrations-billing._
