# @prood/api-client (https://prood.com/docs/packages/api-client)

`@prood/api-client` provides a type-safe HTTP client generated from the Commerce API OpenAPI specification.

## Installation [#installation]

`@prood/api-client` isn't published to npm yet. Available from the source repo for now: in this monorepo, depend on it with `"@prood/api-client": "workspace:*"`.

## Basic usage [#basic-usage]

```ts
import { createCommerceApiClient } from '@prood/api-client'

const api = createCommerceApiClient({
  baseUrl: process.env.COMMERCE_API_URL!, // http://localhost:3005/v1
})

// List products
const { data, error } = await api.GET('/products', {
  params: { query: { query: 'shirt', perPage: 10 } },
})

// Get product by ID
const { data: product } = await api.GET('/products/{id}', {
  params: { path: { id: 'prod_abc' } },
})
```

## With authentication [#with-authentication]

### Session cookie (dashboard) [#session-cookie-dashboard]

```ts
const api = createCommerceApiClient({
  baseUrl: COMMERCE_API_URL,
  cookie: (await headers()).get('cookie') ?? '',
})
```

### Store host (storefront) [#store-host-storefront]

The client sends `host` as the `x-storefront-host` header.

```ts
const api = createCommerceApiClient({
  baseUrl: COMMERCE_API_URL,
  cookie: (await headers()).get('cookie') ?? '',
  host: (await headers()).get('host') ?? '',
})
```

### API key [#api-key]

```ts
const api = createCommerceApiClient({
  baseUrl: COMMERCE_API_URL,
  apiKey: 'pkAbC123...',
})
```

### Agent Auth Bearer token [#agent-auth-bearer-token]

```ts
const api = createCommerceApiClient({
  baseUrl: COMMERCE_API_URL,
  bearerToken: agentJwt,
})
```

## Admin operations [#admin-operations]

```ts
// Create product
await api.POST('/admin/products', { body: createProductInput })

// List orders
const { data: orders } = await api.GET('/admin/orders')

// Fulfill order
await api.POST('/admin/orders/{id}/fulfill', {
  params: { path: { id: orderId } },
  body: { trackingNumber: 'TRK123' },
})

// Dashboard stats
const { data: stats } = await api.GET('/admin/dashboard')
```

## Cart operations [#cart-operations]

```ts
// Create cart
const { data: cart } = await api.POST('/carts')

// Add item
await api.POST('/carts/{id}/items', {
  params: { path: { id: cart.id } },
  body: { productId, variantId, quantity: 1 },
})

// Place order
const { data: order } = await api.POST('/carts/{id}/place-order', {
  params: { path: { id: cart.id } },
})
```

## Type safety [#type-safety]

The client is generated from OpenAPI and provides full TypeScript inference:

```ts
import type { paths } from '@prood/api-client'

// paths['/products']['get']['parameters']['query'] is typed
// paths['/admin/products']['post']['requestBody'] is typed
```

Regenerate types when the API spec changes:

```bash
pnpm --filter @prood/api-client codegen
pnpm --filter @prood/api-client codegen:check
```

## Error handling [#error-handling]

```ts
const { data, error, response } = await api.GET('/products/{id}', {
  params: { path: { id: 'nonexistent' } },
})

if (error) {
  console.log(error.code)    // 'NOT_FOUND'
  console.log(response.status) // 404
}
```

## Related pages [#related-pages]

<Cards>
  <Card title="API endpoints" href="/docs/apps/api/endpoints" description="Complete endpoint reference." />
  <Card title="OpenAPI reference" href="/docs/api" description="Interactive API docs." />
  <Card title="Authentication" href="/docs/apps/api/authentication" description="Auth methods for the client." />
</Cards>
