# API client

> Call the Storeware API for one shop, with tokens that refresh themselves.

Source: https://storeware.ai/docs/sdk/client

```ts
import { ... } from '@storeware/plugin-sdk';
```

### StorewareApiError

```ts
new StorewareApiError(status: number, type: string, message: string, requiredScopes?: string[] | undefined)
```

### StorewareClient

```ts
new StorewareClient(options: StorewareClientOptions)
```

| Name | Type | Description |
| --- | --- | --- |
| `get` | `<T>(path: string) => Promise<T>` |  |
| `post` | `<T>(path: string, body?: unknown) => Promise<T>` |  |
| `patch` | `<T>(path: string, body?: unknown) => Promise<T>` |  |
| `put` | `<T>(path: string, body?: unknown) => Promise<T>` |  |
| `delete` | `<T>(path: string, body?: unknown) => Promise<T>` | A body is rare on a delete, and `cancelOrder` is the one call that takes one. |
| `billing` | `AppBilling` | What this shop pays your app. Ask for a plan or a one-time charge, then send the merchant to its `confirmationUrl`; nothing is owed until they approve. See https://storeware.ai/docs/selling/billing. |
| `settings` | `() => Promise<AppSettingsState>` | What the merchant set for your app on this shop, as your installed release's `[[settings]]` declares it. You hear of a change as `app.settings_updated.v1`. See https://storeware.ai/docs/extensions/settings. |
| `uploadAsset` | `(input: { data: Uint8Array \| ArrayBuffer \| string; contentType: AppAssetContentType; }) => Promise<UploadedAppAsset>` | Puts a picture on Storeware for your components, and gives its address. PNG, JPEG, WebP, GIF or AVIF, at most 5 MB. `data` is the bytes, or a base64 string of them. Needs no permission. |

### StorewareClientOptions

```ts
type StorewareClientOptions = (BaseOptions & {
    refreshToken?: undefined;
}) | (BaseOptions & {
    refreshToken: string;
    clientId: string;
    clientSecret: string;
    onTokensRefreshed: (tokens: StorewareTokens) => void | Promise<void>;
});
```

### QuotedPrices

Prices in every currency Storeware quotes, in minor units. Nothing is converted.

| Name | Type | Description |
| --- | --- | --- |
| `usd` | `number` |  |
| `gbp` | `number` |  |
| `eur` | `number` |  |
| `inr` | `number` |  |

### AppSubscription

| Name | Type | Description |
| --- | --- | --- |
| `id` | `string` |  |
| `plan` | `string` |  |
| `name` | `string` |  |
| `status` | `\| 'pending' \| 'active' \| 'past_due' \| 'frozen' \| 'scheduled' \| 'canceled' \| 'declined' \| 'expired'` |  |
| `amountMinor` | `number` |  |
| `currency` | `'usd' \| 'gbp' \| 'eur' \| 'inr'` |  |
| `interval` | `'month' \| 'year'` |  |
| `test` | `boolean` |  |
| `trialEndsAt` | `string \| null` |  |
| `currentPeriodStart` | `string \| null` |  |
| `currentPeriodEnd` | `string \| null` |  |
| `cancelAtPeriodEnd` | `boolean` |  |
| `createdAt` | `string` |  |
| `confirmationUrl` | `string \| null` | Where to send the merchant while it waits for their answer. |
| `usageCapMinor` | `number \| null` | The most a period's usage may come to, for a plan that charges by use. |
| `usageTerms` | `string \| null` |  |

### AppUsage

A period's usage on the plan in force.

| Name | Type | Description |
| --- | --- | --- |
| `capMinor` | `number` |  |
| `usedMinor` | `number` |  |
| `terms` | `string \| null` |  |

### AppPurchase

| Name | Type | Description |
| --- | --- | --- |
| `id` | `string` |  |
| `name` | `string` |  |
| `amountMinor` | `number` |  |
| `currency` | `'usd' \| 'gbp' \| 'eur' \| 'inr'` |  |
| `test` | `boolean` |  |
| `status` | `'pending' \| 'accepted' \| 'declined' \| 'expired'` |  |
| `createdAt` | `string` |  |
| `confirmationUrl` | `string \| null` |  |

### AppBillingState

| Name | Type | Description |
| --- | --- | --- |
| `currency` | `'usd' \| 'gbp' \| 'eur' \| 'inr'` |  |
| `subscription` | `AppSubscription \| null` |  |
| `usage` | `AppUsage \| null` |  |
| `scheduled` | `AppSubscription \| null` |  |
| `pending` | `{ subscriptions: AppSubscription[]; purchases: AppPurchase[] }` |  |
| `purchases` | `AppPurchase[]` |  |
| `plans` | `{ key: string; name: string; interval: 'month' \| 'year'; amountMinor: number; trialDays: number; }[]` |  |

### AppBilling

| Name | Type | Description |
| --- | --- | --- |
| `state` | `() => Promise<AppBillingState>` |  |
| `requestSubscription` | `(input: { plan: string; returnUrl: string; test?: boolean; idempotencyKey?: string; }) => Promise<AppSubscription>` |  |
| `requestPurchase` | `(input: { name: string; prices: QuotedPrices; returnUrl: string; test?: boolean; idempotencyKey?: string; }) => Promise<AppPurchase>` |  |
| `cancelSubscription` | `(id: string) => Promise<AppSubscription>` |  |
| `recordUsage` | `(input: { amountMinor: number; description: string; idempotencyKey?: string; }) => Promise<{ id: string; amountMinor: number; usage: AppUsage; }>` | What the shop used, in the plan's currency. Refused (402) past the period's cap. |
| `credit` | `(input: { amountMinor: number; description: string; idempotencyKey?: string; }) => Promise<{ id: string; amountMinor: number; currency: string; }>` | A credit on the shop's next statement, in its billing currency. |

### AppSettingsState

What `client.settings()` answers with.

| Name | Type | Description |
| --- | --- | --- |
| `values` | `Record<string, string \| number \| boolean \| null>` | Every field your installed release declares in `[[settings]]`, by key: what the merchant saved, else its default, else null. Secrets in the clear. |
| `updatedAt` | `string \| null` | ISO, or null when the merchant has never saved. |

### AppAssetContentType

The pictures `client.uploadAsset()` takes. Checked by their bytes, so say what they are.

```ts
type AppAssetContentType = 'image/png' | 'image/jpeg' | 'image/webp' | 'image/gif' | 'image/avif';
```

### UploadedAppAsset

| Name | Type | Description |
| --- | --- | --- |
| `url` | `string` | On `cdn.mystoreware.com`, the one host an image in your components may come from. |
| `contentType` | `AppAssetContentType` |  |
| `sizeBytes` | `number` |  |
| `sha256` | `string` |  |
