> ## Documentation Index
> Fetch the complete documentation index at: https://docs.youka.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Xác thực

> Cấu hình YoukaClient bằng API key của bạn

SDK xác thực mọi request bằng API key dạng bearer. Bạn khởi tạo một `YoukaClient` một lần và tái sử dụng nó trong suốt vòng đời của tiến trình.

## `new YoukaClient(options)`

```ts theme={null}
import { YoukaClient } from "@youka/vi/sdk";

const client = new YoukaClient({
  apiKey: process.env.YOUKA_API_KEY!,
});
```

### Options

<ParamField path="apiKey" type="string" required>
  API key Youka của bạn. Tạo một key tại
  [online.youka.io/account](https://online.youka.io/account) trong mục **API keys**.
</ParamField>

<ParamField path="fetch" type="typeof fetch">
  Triển khai `fetch` tuỳ chỉnh. Mặc định là `fetch` toàn cục. Dùng phần này để
  chèn logging, proxy, hoặc middleware retry tuỳ chỉnh.
</ParamField>

## Lưu trữ API key

<Warning>
  API key cấp quyền truy cập vào thông tin thanh toán của bạn. Không bao giờ commit chúng lên hệ thống quản lý mã nguồn.
</Warning>

Các mẫu khuyến nghị:

<Tabs>
  <Tab title="Environment variable">
    ```ts theme={null}
    const client = new YoukaClient({
      apiKey: process.env.YOUKA_API_KEY!,
    });
    ```
  </Tab>

  <Tab title="Secret manager">
    ```ts theme={null}
    import { getSecret } from "./my-secret-manager";

    const client = new YoukaClient({
      apiKey: await getSecret("youka-api-key"),
    });
    ```
  </Tab>
</Tabs>

## Inject một fetch tuỳ chỉnh

Mọi phương thức SDK đều dùng `fetch` bạn truyền vào constructor. Điều này giúp dễ dàng thêm logging hoặc middleware:

```ts theme={null}
import { YoukaClient } from "@youka/vi/sdk";

const instrumentedFetch: typeof fetch = async (input, init) => {
  const start = Date.now();
  const response = await fetch(input, init);
  console.log(
    `${init?.method ?? "GET"} ${input} ${response.status} in ${Date.now() - start}ms`,
  );
  return response;
};

const client = new YoukaClient({
  apiKey: process.env.YOUKA_API_KEY!,
  fetch: instrumentedFetch,
});
```

## Tuỳ chọn theo từng request

Mỗi phương thức chấp nhận một đối số thứ hai hoặc thứ ba (không bắt buộc) với các tuỳ chọn ở cấp request:

```ts theme={null}
await client.projects.create(body, {
  idempotencyKey: "import-2026-04-08-song-001",
  signal: abortController.signal,
});
```

<ParamField path="idempotencyKey" type="string">
  Được truyền dưới dạng header `Idempotency-Key`. Tái sử dụng cùng một key với cùng
  payload sẽ trả về kết quả ban đầu thay vì tạo bản trùng lặp. Xem [API
  idempotency](/vi/api/idempotency).
</ParamField>

<ParamField path="signal" type="AbortSignal">
  Abort signal tiêu chuẩn. Huỷ các request đang chạy và các lượt poll chạy lâu
  của `client.tasks.wait(...)`, `client.projects.wait(...)`, và
  `client.exports.wait(...)`.
</ParamField>

## Tiếp theo

* [Projects](/vi/sdk/projects) — tạo project đầu tiên của bạn
* [Errors](/vi/sdk/errors) — xử lý lỗi xác thực
* [API authentication](/vi/api/authentication) — chi tiết header HTTP thô
