SDK et CLI

Piloter FORGE depuis votre code avec les SDK TypeScript et Python, ou depuis le terminal avec la CLI : runs, Live, batches, idempotence, pagination et erreurs.

Les SDK TypeScript et Python et la CLI forge couvrent toute l'API REST : agents, runs, Live, batches, planifications, campagnes, revues, crédits. Ils gèrent pour vous l'authentification, les nouvelles tentatives, la pagination et la reconnexion au flux Live.

Clé API

Créez une clé dans Développeurs ou avec forge keys create, en la limitant aux scopes utiles (agents:read, runs:write, batches:write…). Le secret fk_live_… n'est affiché qu'une fois. Les SDK et la CLI lisent FORGE_API_KEY, et FORGE_API_URL pour l'adresse de l'API.

export FORGE_API_KEY=fk_live_…
export FORGE_API_URL=https://api.forge.example

SDK TypeScript

// npm install @forge/sdk
import { Forge } from '@forge/sdk';

const forge = new Forge({ apiKey: process.env.FORGE_API_KEY, baseUrl: 'https://api.forge.example' });

const run = await forge.runs.create({
  agentId: '8f1c2a4e-…',
  input: { company_name: 'ACME SAS' },
  effort: 'low',
  maxCostEur: 0.5,
});

// Fil d'activité en direct (SSE, reconnexion automatique)
for await (const ev of forge.runs.live(run.id)) {
  console.log(ev.kind, ev.summary);
}

const done = await forge.runs.wait(run.id, { timeoutMs: 5 * 60_000 });
console.log(done.status, done.structured_output);

SDK Python

# pip install forge-sdk
import os
from forge import Forge

forge = Forge(api_key=os.environ["FORGE_API_KEY"])

run = forge.runs.create(agent_id="8f1c2a4e-…", input={"company_name": "ACME SAS"}, effort="low")
for ev in forge.runs.live(run.id):
    print(ev.kind, ev.summary)

# Batch sur des lignes en mémoire, puis lecture des résultats
batch = forge.batches.create(agent_id="8f1c2a4e-…", rows=[{"siren": "123456789"}], max_credits=500)
forge.batches.wait(batch.id)
for row in forge.batches.results(batch.id):
    print(row.entity_key, row.status, row.output)

CLI

forge login                     # enregistre la clé dans ~/.config/forge/config.json
forge whoami
forge agents list --search kyb
forge runs create --agent 8f1c2a4e-… --input '{"company_name":"ACME SAS"}' --effort low --wait
forge runs create --agent 8f1c2a4e-… --input @entree.json --max-cost 1 --live
forge runs live <run_id>        # fil d'activité dans le terminal ; Ctrl+C quitte, le run continue
forge runs control <run_id> steer "Ignore la filiale belge"
forge balance
forge keys create --label ci-kyb --scopes agents:read,runs:write --expires-in-days 90

Idempotence, pagination, erreurs

  • Idempotence : chaque POST porte un en-tête Idempotency-Key. Les SDK en génèrent un, stable entre les nouvelles tentatives ; passez le vôtre (idempotencyKey en TypeScript, idempotency_key en Python) pour dédoublonner côté métier.
  • Nouvelles tentatives : 3 par défaut sur 408, 429, 5xx et erreurs réseau, avec backoff exponentiel et respect de Retry-After.
  • Pagination : les listes sont paginées par curseur (limit jusqu'à 100, next_cursor). Les SDK itèrent pour vous : for await (const a of forge.agents.list()) en TypeScript, for a in forge.agents.list() en Python, ou toArray() et to_list().
  • Erreurs typées : le corps { error: { code, message, field, docs_url } } devient une exception précise, comme AuthenticationError, InsufficientCreditsError, NotFoundError, ValidationError, BudgetExceededError ou RateLimitedError. Toutes héritent de ForgeApiError.
import { ForgeApiError, InsufficientCreditsError } from '@forge/sdk';

try {
  await forge.runs.create(
    { agentId, input: { company_name: 'ACME SAS' } },
    { idempotencyKey: 'kyb-acme-2026-10-12' },
  );
} catch (err) {
  if (err instanceof InsufficientCreditsError) {
    // Proposer une recharge de crédits
  } else if (err instanceof ForgeApiError) {
    console.error(err.status, err.code, err.message, err.requestId);
  } else {
    throw err;
  }
}
La CLI accepte --json pour une sortie exploitable dans vos scripts, et --org <id> pour cibler une autre organisation. Côté Python, AsyncForge offre les mêmes méthodes en asynchrone.