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

# Bibliothèque cliente JavaScript

> Installer, initialiser, mapper les méthodes aux endpoints et gérer les erreurs avec le SDK JavaScript/TypeScript officiel octoparse-client.

`octoparse-client` est le client JavaScript/TypeScript officiel pour Data Hub. Il encapsule uniquement l’API REST publique `/v1` et n’a aucune dépendance d’exécution. Les méthodes correspondent une à une aux endpoints, les noms de paramètres sont en camelCase côté client et convertis en snake\_case REST, et les valeurs renvoyées sont la charge utile `data` brute. Version actuelle 0.2.9, Node.js 18+.

## Installation

```bash theme={null}
npm install octoparse-client
```

## Initialisation

```js theme={null}
import { Client } from "octoparse-client";

const client = new Client({ apiKey: "<your API key>" });
```

| Paramètre | Description                                                                                                                                              |
| --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `apiKey`  | Clé API Data Hub. Si omise, lit `OCTOPARSE_API_KEY`. Si elle manque encore, le client est anonyme et ne peut appeler que les endpoints anonymes.         |
| `baseUrl` | URL du service. Si omise, lit `OCTOPARSE_BASE_URL`, par défaut `https://api-datahub.octoparse.com`. Passez-la explicitement pour le local ou le staging. |
| `timeout` | Timeout HTTP par requête en millisecondes. Défaut 90000.                                                                                                 |

## Correspondance méthode-endpoint

| Méthode                                                             | Endpoint                                  | Notes                                                 |
| ------------------------------------------------------------------- | ----------------------------------------- | ----------------------------------------------------- |
| `meta()`                                                            | `GET /v1/meta`                            | Constantes de la plateforme                           |
| `search(q, { limit, offset, ... })`                                 | `GET /v1/data-apps`                       | Une page de cartes, avec `pagination`                 |
| `getApp(appId)`                                                     | `GET /v1/data-apps/{app_id}`              | Détail complet de l’app                               |
| `run(appId, inputs, { wait, maxRecords, version, build })`          | `POST /v1/data-apps/{app_id}/runs`        | Démarrer une exécution                                |
| `call(appId, inputs, { maxRecords, timeout, raiseOnFailure, ... })` | `POST` + sondage                          | Aide bloquante : attend l’état terminal ou le timeout |
| `getRun(runId, { wait })`                                           | `GET /v1/runs/{run_id}`                   | Statut et snapshot de facturation                     |
| `listRunsPage(filters)`                                             | `GET /v1/runs`                            | Une page d’exécutions, avec `pagination`              |
| `listRuns(filters)`                                                 | `GET /v1/runs`                            | Une page d’exécutions, items uniquement               |
| `iterateRuns(filters)`                                              | `GET /v1/runs`                            | Itérateur asynchrone qui pagine automatiquement       |
| `cancel(runId)`                                                     | `POST /v1/runs/{run_id}/cancel`           | Annuler une exécution                                 |
| `getRecords(runId, { offset, limit, fields })`                      | `GET /v1/runs/{run_id}/records`           | Une page d’enregistrements de résultat                |
| `iterateRecords(runId, { batch, fields })`                          | `GET /v1/runs/{run_id}/records`           | Itérateur asynchrone qui pagine automatiquement       |
| `exportRecords(runId, format)`                                      | `GET /v1/runs/{run_id}/records`           | Export complet en texte `jsonl` / `csv`               |
| `listDatasets({ offset, limit })`                                   | `GET /v1/datasets`                        | Liste des datasets                                    |
| `setDatasetRetention(datasetId, retained)`                          | `PUT /v1/datasets/{dataset_id}/retention` | Définir le flag de rétention                          |
| `getDatasetRecords(datasetId, { offset, limit, fields })`           | `GET /v1/datasets/{dataset_id}/records`   | Une page d’enregistrements du dataset                 |
| `iterateDatasetRecords(datasetId, { batch, fields })`               | `GET /v1/datasets/{dataset_id}/records`   | Itérateur asynchrone qui pagine automatiquement       |
| `account()`                                                         | `GET /v1/account`                         | Infos du compte et dépenses cumulées                  |
| `billing({ groupBy, createdFrom, createdTo, tzOffset })`            | `GET /v1/billing`                         | Agrégation de facturation                             |

Les `filters` de liste d’exécutions acceptent `status`, `dataApp`, `triggeredBy`, `runKind`, `credential`, `createdFrom`, `createdTo`, plus `offset` / `limit`. Les endpoints de publication, d’opérations et de secrets ne sont pas encapsulés ; appelez REST directement.

## Usage typique

```js theme={null}
import { Client, ApiError, RunFailed } from "octoparse-client";

const client = new Client({ apiKey: "<your API key>" });

// Découvrir
const { items } = await client.search("reviews", { limit: 5 });
for (const card of items) console.log(card.app_id, card.namespace, card.app_name);
const detail = await client.getApp("carol/reviews-query");

// Exécuter et consommer. Les timeouts sont en millisecondes. TimeoutError n’annule pas l’exécution côté serveur.
const run = await client.call("carol/reviews-query", { product: "p-9001" }, {
  maxRecords: 100, timeout: 120_000, raiseOnFailure: true,
});
for await (const record of client.iterateRecords(run.run_id)) {
  console.log(record);
}

// Non bloquant : démarrez, puis sondez vous-même
const started = await client.run("carol/reviews-query", { product: "p-9002" }, { wait: 0 });
const polled = await client.getRun(started.run_id, { wait: 60 });

// Rapprocher les dépenses
console.log(await client.billing({ groupBy: "data_app", tzOffset: 480 }));
for await (const r of client.iterateRuns({ createdFrom: "2026-09-01T00:00:00+08:00" })) {
  console.log(r.run_id, r.status, r.billing.total);
}

// Les résultats sont conservés 90 jours par défaut ; marquez les datasets à garder plus longtemps
await client.setDatasetRetention(run.dataset_id, true);
```

## Gestion des erreurs

Les réponses d’erreur de l’API lèvent `ApiError` (étend `Error`). Les champs correspondent à l’objet REST `error` :

| Propriété    | Signification                                                                           |
| ------------ | --------------------------------------------------------------------------------------- |
| `statusCode` | Statut HTTP                                                                             |
| `code`       | Id d’erreur stable pour brancher                                                        |
| `category`   | Classe large                                                                            |
| `message`    | Description en anglais                                                                  |
| `retryable`  | Si la même requête peut être retentée                                                   |
| `details`    | Problèmes au niveau des champs en cas d’échec de validation d’entrée, sinon `undefined` |

```js theme={null}
import { ApiError } from "octoparse-client";

try {
  await client.run("carol/reviews-query", {});
} catch (e) {
  if (e instanceof ApiError && e.code === "invalid-input") {
    for (const d of e.details ?? []) console.log(d.path, d.message);
  } else if (e instanceof ApiError && e.retryable) {
    // backoff puis réessai
  } else {
    throw e;
  }
}
```

`RunFailed` est levé quand `call()` utilise `raiseOnFailure: true` et que l’exécution se termine en `FAILED` / `CANCELLED` / `EXPIRED`. Sa propriété `run` contient l’objet d’exécution complet.

## Références d’app

`getApp()`, `run()`, `call()` et le filtre `dataApp` de la liste d’exécutions acceptent les deux formes : deux segments `<namespace>/<app_name>` (lisible, cassé après renommage) et `app_id` stable (`app_<hex>`, survit au renommage). Pour les intégrations durables, stockez `app_id`. Les apps partagées point à point sont absentes de la recherche marketplace ; utilisez `search("", { sharedWith: "me" })`.
