Aller au contenu principal
Référence développeur

SDKs officiels & Référence API

La référence complète pour intégrer Scell.io. SDKs type-safe pour TypeScript et PHP, plus un agent MCP pour les workflows IA. Chaque ressource, chaque méthode, entièrement documentée.

TypeScript

TypeScript SDK

TypeScript / JavaScript

v2.25.0

Installation

npm install @scell/sdk

Fonctionnalités

  • Typage TypeScript complet (strict mode)
  • API async/await basée sur les Promises
  • 4 classes client (Bearer, API Key, Tenant, Public)
  • Factures B2B + B2C, avoirs, signatures, fiscal, webhooks
  • Invoice Templates (upload logo + couleurs + mentions)
  • Coordonnées bancaires Factur-X (IBAN/BIC) + délai paiement par défaut
  • Clôture journalière auto + email + CSV
  • Auto-attestation ISCA nominative (tenant + sub_tenant)
  • Mode sandbox avec préfixe sk_test_
  • Paiement Stripe en ligne des factures Scell.io (depuis v2.2.0)
  • Sub-tenants management : delete cascade ISCA + SuperPDP authorize URL (depuis v2.9.0)
  • Receipt OpenTimestamps `ots_proof_base64` sur les clôtures fiscales (depuis v2.10.0)
  • Signature blocks : paraphe automatique + mentions juridiques + date du jour (depuis v2.12.0)
  • Devis (Quotes) : CRUD, envoi par email, signature, conversion en acomptes (depuis v2.13.0)
  • PaymentSchedule complet : set/patch/delete/summary/convertLine/presets (depuis v2.13.0)
  • Quote `callback_url` : redirige le buyer vers le site tenant après accept/refuse (depuis v2.13.1)
  • `PaymentSummary.lines[]` : tracker visuel complet sans seconde requête (depuis v2.14.0)
  • invoices.update() / delete() + creditNotes.update() / delete() — brouillons uniquement (depuis v2.16.0)
  • Initiales multi-pages : `initials_block.positions[]` avec position et style override par page (depuis v2.17.0)
  • Webhook secret affiché 1 fois à création / régénération + `secret_last4` pour fingerprint (depuis v2.19.0)
  • `parent_quote_id` sur facture standard : lien soft vers un devis source pour la traçabilité (depuis v2.21.0)
  • Statuts `refunded` / `partially_refunded` posés automatiquement par le backend + champs `refund_status` et `total_refunded` exposés (depuis v2.22.0)
  • Couverture exhaustive des énumérations : 19 union types stricts (`InvoiceType`, `QuoteStatus`, `VatCategory`, `SignatureStatus`, etc.) — fin des `string` génériques côté SDK (depuis v2.23.0)
  • BT-81 Payment Means Code : conformité Factur-X EN16931 avec les 11 codes UN/ECE 4461 (depuis v2.25.0)
PHP

PHP SDK

PHP 8.2+

v2.25.0

Installation

composer require scell/sdk

Fonctionnalités

  • PHP 8.2+ avec types stricts (readonly DTOs)
  • Autoloading PSR-4
  • Auto-discovery Laravel (config/scell.php)
  • 4 classes client (Bearer, API Key, Tenant, Public)
  • Factures B2B + B2C, avoirs, signatures, fiscal, webhooks
  • Invoice Templates (upload logo + couleurs + mentions)
  • Coordonnées bancaires Factur-X (IBAN/BIC) + délai paiement par défaut
  • Auto-attestation ISCA nominative (tenant + sub_tenant)
  • Builder fluent (buyerIndividual, asB2c, etc.)
  • Mode sandbox intégré
  • Paiement Stripe en ligne des factures Scell.io (depuis v2.2.0)
  • Sub-tenants management : delete cascade ISCA + SuperPDP authorize URL (depuis v2.9.0)
  • Receipt OpenTimestamps `ots_proof_base64` sur les clôtures fiscales (depuis v2.10.0)
  • Signature blocks : DTOs InitialsBlock + Mention + DateBlock (depuis v2.12.0)
  • Devis (Quotes) : CRUD + QuoteBuilder fluent (depuis v2.13.0)
  • QuotePaymentScheduleResource : list/set/patch/delete/summary/convertLine/presets (depuis v2.13.0)
  • QuoteBuilder::callbackUrl() : redirige le buyer vers le site tenant après accept/refuse (depuis v2.13.1)
  • invoices()->update() / delete() + creditNotes()->update() / delete() — brouillons uniquement (depuis v2.14.0)
  • Initiales multi-pages : DTO `InitialsPosition` + `InitialsBlock::withPositions([...])` (depuis v2.15.0)
  • DTO `Webhook::$secret_last4` + secret affiché 1 fois à création (depuis v2.17.0)
  • `InvoiceBuilder::parentQuoteId()` sur facture standard : lien soft vers un devis source (depuis v2.19.0)
  • Enum `InvoiceStatus` complet (refunded, partially_refunded) + champs `refund_status` et `total_refunded` sur le DTO Invoice (depuis v2.20.0)
  • Couverture exhaustive des énumérations : 19 classes d'enum typées dans `Scell\Sdk\Enums\*` (`InvoiceType`, `QuoteStatus`, `VatCategory`, `SignatureStatus`, etc.) — fin des `string` génériques côté DTO (depuis v2.21.0)
  • BT-81 Payment Means Code : enum `PaymentMeansCode` avec les 11 codes UN/ECE 4461 pour conformité Factur-X EN16931 (depuis v2.25.0)
🤖

MCP Agent

Claude Desktop / Cursor / VS Code

v2.25.0

Installation

npx -y mcp-remote https://api.scell.io/api/mcp

Fonctionnalités

  • Compatible protocole MCP
  • Claude Desktop, Cursor, VS Code, autres LLM
  • 98 outils : factures B2B/B2C, avoirs, signatures, fiscal, templates, sub-tenants, buyers, branding, billing, credit packs, mark-paid BT-81 (depuis v2.25.0)
  • Templates invoice avec upload logo + couleurs (one-time setup)
  • Auto-attestation ISCA nominative (tenant + sub_tenant) en 1 prompt
  • Heuristiques LLM B2C (particulier, individual, M./Mme/...)
  • Zéro dépendance d'exécution
  • Support du mode sandbox
  • Paiement Stripe d'une facture Scell.io en 1 prompt (depuis v2.2.0)
  • Signature blocks : initialsBlock + mentions + dateBlock en camelCase LLM-friendly (depuis v2.12.0)
  • scell_mark_invoice_paid : marquer une facture sortante comme payée (depuis v2.15.0)
  • Initiales multi-pages : `initialsBlock.positions[]` (1 entrée par page avec overrides) découvrable par le LLM (depuis v2.16.0)
  • `parentQuoteId` sur facture standard : lien soft vers un devis source pour la traçabilité (depuis v2.20.0)
  • Statuts `refunded` / `partially_refunded` automatiques + champs `refundStatus` et `totalRefunded` discoverables par le LLM (depuis v2.21.0)
  • Couverture exhaustive des énumérations : descriptions d'outils enrichies avec les valeurs autorisées des 19 énumérations de l'API (le LLM voit le vocabulaire complet, fin des erreurs 422 dues à des valeurs inventées) (depuis v2.22.0)
  • BT-81 Payment Means Code : conformité Factur-X EN16931 avec les 11 codes UN/ECE 4461 (depuis v2.25.0)

Installation

Installez le SDK officiel Scell.io pour votre plateforme. Les trois options se connectent à la même API.

TypeScript / PHP

terminal
typescript
npm install @scell/sdk
# or with yarn
yarn add @scell/sdk
# or with pnpm
pnpm add @scell/sdk

MCP Agent

~/.claude/.mcp.json
json
// Coller ce bloc dans le fichier de config MCP de votre client IA.
// Cree le fichier s'il n'existe pas (chemin selon le client) :
//
//   - Claude Code (CLI)   ~/.claude/.mcp.json
//   - Claude Desktop      ~/Library/Application Support/Claude/claude_desktop_config.json   (macOS)
//                         %APPDATA%\\Claude\\claude_desktop_config.json                  (Windows)
//   - Cursor              ~/.cursor/mcp.json
//   - VS Code (Copilot)   ~/.vscode/mcp.json
//
// Remplacer sk_live_xxxx par votre cle Scell.io (sk_live_* en prod, sk_test_* en sandbox).
// Recuperez vos cles depuis le dashboard : https://app.scell.io/dashboard/api-keys

{
  "mcpServers": {
    "scell": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://api.scell.io/api/mcp",
        "--header",
        "X-Scell-API-Key: sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
      ]
    }
  }
}

Authentification

Scell.io supporte trois modes d'authentification, chacun avec une classe client dédiée.

ModeClasse clientPréfixe de cléCas d'usage
Bearer TokenScellClientSanctum tokenSessions dashboard, opérations utilisateur
Secret API KeyScellApiClient / ScellTenantClientsk_live_* / sk_test_*Serveur à serveur. Headers acceptés : X-API-Key OU X-Tenant-Key (alias historique).
Publishable KeyScellPublicClientpk_live_* / pk_test_*Widget public d'onboarding (browser-safe). Header X-Publishable-Key.

Bearer Token (Dashboard)

Utilisez ScellClient avec un bearer token Sanctum pour les opérations utilisateur dashboard. Ressources : auth, companies, apiKeys, balance, webhooks, invoices (lecture), signatures (lecture).

auth-bearer.ts
typescript
import { ScellClient } from '@scell/sdk';
// Authenticate with a Sanctum bearer token (dashboard sessions)
const client = new ScellClient('your_bearer_token');
// Resources available on ScellClient:
// client.auth — login, register, logout, me
// client.companies — CRUD on companies + KYC
// client.apiKeys — manage API keys
// client.balance — check balance, reload, transactions
// client.webhooks — manage webhooks
// client.invoices — read-only invoice access
// client.signatures — read-only signature access
const me = await client.auth.me();
console.log(me.email);

Clé API (Serveur à serveur)

Utilisez ScellApiClient avec une clé secrète (sk_live_* ou sk_test_*) pour les opérations serveur à serveur complètes. Ressources : invoices, signatures, creditNotes, subTenants, fiscal, stats, billing, tenantInvoices, tenantCreditNotes, incomingInvoices.

auth-api-key.ts
typescript
import { ScellApiClient } from '@scell/sdk';
// Production
const client = new ScellApiClient('sk_live_your_api_key');
// Sandbox mode (sk_test_ prefix)
const sandbox = new ScellApiClient('sk_test_your_api_key');
// Une cle sk_* appartient au tenant master. Pour cibler un sub-tenant,
// passer sub_tenant_id dans le payload POST (factures, signatures, avoirs).
// Sans sub_tenant_id : action sur le tenant master, company emettrice =
// tenant.default_company_id (configure depuis le dashboard Profil).
// Resources available on ScellApiClient:
// client.invoices — full invoice CRUD + submit + download
// client.signatures — full signature CRUD + cancel + remind
// client.creditNotes — credit note management
// client.subTenants — manage sub-tenants
// client.fiscal — fiscal compliance (ISCA)
// client.stats — overview + monthly statistics
// client.billing — billing, usage, top-up
// client.tenantInvoices — tenant direct invoices (CRUD + submit + download Factur-X/UBL/CII)
// client.tenantCreditNotes — tenant credit notes
// client.incomingInvoices — incoming invoice management

ScellTenantClient — header X-Tenant-Key (alias historique)

⚠ Important — il n'existe PAS de format de clé tk_* distinct. ScellTenantClient accepte la même clé secrète sk_live_* / sk_test_* que ScellApiClient. La seule différence : il envoie le header X-Tenant-Key au lieu de X-API-Key. Cote serveur, le middleware TenantApiKeyMiddleware lit X-Tenant-Key ?? X-API-Key et valide la même regex /^sk_(live|test)_[A-Za-z0-9]{32}$/ — donc les deux clients fonctionnent avec n'importe laquelle de vos clés sk_*. Conserve pour la rétro-compatibilité ; préférer ScellApiClient (header X-API-Key) dans le code nouveau.

Le client ScellTenantClient expose en plus quelques méthodes directes pratiques : me(), updateProfile(), balance(), quickStats(), regenerateKey(). Tout le reste (invoices, signatures, sub_tenants…) est strictement identique à ScellApiClient.

auth-tenant.ts
typescript
import { ScellTenantClient } from '@scell/sdk';
// IMPORTANT — meme cle secrete que ScellApiClient (sk_*).
// La SEULE difference : ce client envoie le header X-Tenant-Key
// au lieu de X-API-Key. Il n'existe PAS de format tk_* distinct.
// Production
const client = new ScellTenantClient('sk_live_your_secret_key');
// Sandbox mode
const sandbox = new ScellTenantClient('sk_test_your_secret_key');
// Resources:
// client.directInvoices — create invoices for sub-tenants
// client.directCreditNotes — create credit notes
// client.incomingInvoices — manage incoming invoices
// client.subTenantCreditNotes — sub-tenant credit notes
// client.fiscal — fiscal compliance
// client.billing — billing & usage
// client.stats — statistics
// client.subTenants — manage sub-tenants
// Direct methods on ScellTenantClient:
// client.me() — tenant profile
// client.updateProfile() — update profile
// client.balance() — check balance
// client.quickStats() — summary stats
// client.regenerateKey() — regenerate tenant key

Référence API

Référence complète des méthodes pour chaque ressource SDK. Exemples de code en TypeScript et PHP pour chaque ressource.

Factures

13 méthodes

Créez, validez, soumettez et téléchargez des factures électroniques aux formats Factur-X, UBL et CII. Disponible sur ScellApiClient (CRUD complet) et ScellClient (lecture seule).

MéthodeDescription
list(options?)Lister les factures avec pagination et filtres optionnels
get(id)Obtenir une facture par son UUID
create(data)Créer une facture (format Factur-X, UBL ou CII)
submit(id)Soumettre une facture au réseau PDP (Peppol / Chorus Pro)
markPaid(id)Marquer comme payée (paiement manuel, statuts acceptés : validated/transmitted/sent/accepted)
sendByEmail(id, data?)Envoyer la facture Factur-X par email au buyer
download(id, format)Télécharger en PDF, XML ou Factur-X. format : "pdf" | "xml" | "facturx"
auditTrail(id)Obtenir la piste d'audit complète (création, validation, soumission…)
convert(data)Convertir entre formats de facture (Factur-X ↔ UBL ↔ CII)
incoming(options?)Lister les factures entrantes (reçues via le PDP)
accept(id, data?)Accepter une facture entrante (PDP)
reject(id, reason, code)Rejeter une facture entrante avec motif et code
dispute(id, reason, code)Contester une facture entrante (litige)

Créer une facture

create.ts
typescript
import { ScellApiClient } from '@scell/sdk';
const scell = new ScellApiClient('sk_live_your_api_key');
// ── B2B Invoice (Factur-X) ──────────────────────────────────────────
const { data: invoice } = await scell.invoices.create({
direction: 'outgoing',
output_format: 'facturx', // 'facturx' | 'ubl' | 'cii'
invoice_date: '2026-06-01',
due_date: '2026-07-01',
currency: 'EUR',
// Seller (flat fields — server validates per country)
seller_name: 'QR Communication SAS',
seller_siret: '90347842500015', // required if seller_country=FR
seller_vat_number: 'FR42903478425',
seller_country: 'FR',
seller_address: {
line1: '123 Avenue de la République',
postal_code: '75011',
city: 'Paris',
country: 'FR',
},
// Buyer — option 1: flat fields
buyer_name: 'GN IMMO',
buyer_siret: '49438068600076', // required if buyer_country=FR && !buyer_is_individual
buyer_vat_number: 'FR42494380686',
buyer_country: 'FR',
buyer_address: {
line1: '453 Route Nationale 7',
postal_code: '13670',
city: 'Verquières',
country: 'FR',
},
// Amounts (HT + TVA = TTC)
total_ht: 2500.00,
total_tva: 500.00,
total_ttc: 3000.00,
// Lines (min 1)
lines: [
{
description: 'Prestation conseil transformation digitale',
quantity: 10,
unit: 'HUR', // UN/ECE Rec 20 (optional)
unit_price_ht: 250.00,
tva_rate: 20.0, // 0 | 5.5 | 10 | 20
total_ht: 2500.00,
total_ttc: 3000.00,
},
],
});
console.log(invoice.invoice_number); // 'FAC-2026-000042'
console.log(invoice.status); // 'draft'
console.log(invoice.download_url); // presigned S3 URL
// ── B2C Invoice (individual — no SIRET/VAT required) ────────────────
const { data: b2cInvoice } = await scell.invoices.create({
direction: 'outgoing',
output_format: 'facturx',
invoice_date: '2026-06-01',
due_date: '2026-06-15',
currency: 'EUR',
seller_name: 'QR Communication SAS',
seller_siret: '90347842500015',
seller_country: 'FR',
seller_address: { line1: '123 Avenue de la République', postal_code: '75011', city: 'Paris', country: 'FR' },
buyer_name: 'Marie Dupont',
buyer_is_individual: true, // BT-46/47/48 omitted, no L441-10
buyer_country: 'FR',
buyer_address: { line1: '12 Rue des Lilas', postal_code: '75011', city: 'Paris', country: 'FR' },
total_ht: 150.00,
total_tva: 30.00,
total_ttc: 180.00,
lines: [{ description: 'Formation individuelle', quantity: 1, unit_price_ht: 150.00, tva_rate: 20.0, total_ht: 150.00, total_ttc: 180.00 }],
});
// ── With buyer_id (registry shortcut) ───────────────────────────────
const { data: fromRegistry } = await scell.invoices.create({
direction: 'outgoing',
output_format: 'facturx',
invoice_date: '2026-06-01',
due_date: '2026-07-01',
currency: 'EUR',
seller_name: 'QR Communication SAS',
seller_siret: '90347842500015',
seller_country: 'FR',
seller_address: { line1: '123 Avenue de la République', postal_code: '75011', city: 'Paris', country: 'FR' },
buyer_id: '019e2dbe-362a-7105-87a5-f45fad1382ed', // auto-snapshot
total_ht: 2500.00,
total_tva: 500.00,
total_ttc: 3000.00,
lines: [{ description: 'Consulting', quantity: 10, unit_price_ht: 250.00, tva_rate: 20.0, total_ht: 2500.00, total_ttc: 3000.00 }],
});
// ── Sub-tenant scoping ──────────────────────────────────────────────
const { data: subInvoice } = await scell.invoices.create({
sub_tenant_id: '019d5ea8-0000-0000-0000-000000000000',
direction: 'outgoing',
output_format: 'facturx',
invoice_date: '2026-06-01',
due_date: '2026-07-01',
currency: 'EUR',
buyer_id: '019e2dbe-362a-7105-87a5-f45fad1382ed',
total_ht: 1000.00,
total_tva: 200.00,
total_ttc: 1200.00,
lines: [{ description: 'Service', quantity: 1, unit_price_ht: 1000.00, tva_rate: 20.0, total_ht: 1000.00, total_ttc: 1200.00 }],
});
// ── Standard invoice from a quote (parent_quote_id, since v2.21.0) ──
// Lien soft vers un devis source pour tracabilite (devis -> facture).
// IMPORTANT : parent_quote_id est accepte UNIQUEMENT pour invoice_type='standard'
// (ou champ omis). Pour une facture d'acompte ou de solde, utiliser les
// endpoints dedies POST /quotes/{id}/convert-to-deposit / convert-to-balance.
// Backend : 404 PARENT_QUOTE_NOT_FOUND si le devis n'appartient pas au tenant,
// 422 si invoice_type='deposit' ou 'balance' est combine avec parent_quote_id.
const { data: fromQuote } = await scell.invoices.create({
direction: 'outgoing',
output_format: 'facturx',
invoice_date: '2026-06-01',
due_date: '2026-07-01',
currency: 'EUR',
parent_quote_id: '019e3f00-7c8d-7000-9000-000000000001', // UUID du devis source
buyer_id: '019e2dbe-362a-7105-87a5-f45fad1382ed',
total_ht: 2500.00,
total_tva: 500.00,
total_ttc: 3000.00,
lines: [{ description: 'Consulting (devis DEV-2026-0042)', quantity: 10, unit_price_ht: 250.00, tva_rate: 20.0, total_ht: 2500.00, total_ttc: 3000.00 }],
});

Modifier un brouillon

update.ts
typescript
import { ScellApiClient } from '@scell/sdk';
const scell = new ScellApiClient('sk_live_your_api_key');
// Update a draft invoice (only draft status allowed)
// All fields are optional — partial update via PUT /invoices/{id}
const { data: invoice } = await scell.invoices.update(
'019dfae2-abef-73e4-b6b2-e4cdae938f3b',
{
// Change due date
due_date: '2026-08-15',
// Update buyer info
buyer_name: 'GN IMMO — Siège social',
buyer_email: 'comptabilite@gnimmo.com',
// Update buyer address
buyer_address: {
line1: '453 Route Nationale 7',
postal_code: '13670',
city: 'Verquières',
country: 'FR',
},
// Add shipping address (BG-13 EN16931)
buyer_shipping_address: {
name: 'Entrepôt Lyon',
line1: '15 Rue de l\'Industrie',
postal_code: '69003',
city: 'Lyon',
country: 'FR',
},
// Replace lines entirely
lines: [
{
description: 'Audit transformation digitale',
quantity: 5,
unit_price: 300.00,
vat_rate: 20.0,
},
{
description: 'Accompagnement mensuel',
quantity: 3,
unit_price: 500.00,
vat_rate: 20.0,
},
],
}
);
console.log(invoice.status); // still 'draft'

Soumettre au PDP

submit.ts
typescript
import { ScellApiClient } from '@scell/sdk';
const scell = new ScellApiClient('sk_live_your_api_key');
// Submit a draft invoice to the PDP network (Peppol/Chorus Pro)
// Idempotent — calling twice returns the same transmitted_at
const invoice = await scell.invoices.submit('019dfae2-abef-73e4-b6b2-e4cdae938f3b');
console.log(invoice.status); // 'transmitted'
console.log(invoice.transmitted_at); // ISO 8601
// Bulk submit multiple invoices at once
const results = await scell.invoices.bulkSubmit([
'019dfae2-abef-73e4-b6b2-e4cdae938f3b',
'019dfae2-abef-73e4-b6b2-e4cdae938f3c',
]);

Marquer comme payée

mark-paid.ts
typescript
import { ScellApiClient } from '@scell/sdk';
const scell = new ScellApiClient('sk_live_your_api_key');
// Mark an outgoing invoice as paid (manual payment)
// Accepted statuses: validated, transmitted, sent, accepted
// Returns 422 INVOICE_NOT_PAYABLE if status is draft or already paid
const { data: invoice } = await scell.invoices.markPaid(
'019dfae2-abef-73e4-b6b2-e4cdae938f3b'
);
// invoice.status === 'paid'
// invoice.paid_at === '2026-06-15T14:30:00Z'
// invoice.payment_method === 'manual'
// With optional payment details
const { data: detailed } = await scell.invoices.markPaid(
'019dfae2-abef-73e4-b6b2-e4cdae938f3b',
{
payment_reference: 'VIR-2026-0542',
paid_at: '2026-06-14T09:00:00Z',
note: 'Virement reçu — relevé BNP 06/2026',
}
);

Télécharger (PDF / XML / Factur-X)

download.ts
typescript
import { ScellApiClient } from '@scell/sdk';
import { writeFileSync } from 'node:fs';
const scell = new ScellApiClient('sk_live_your_api_key');
// Download as Factur-X (PDF/A-3b + embedded CII XML)
const facturx = await scell.invoices.download(
'019dfae2-abef-73e4-b6b2-e4cdae938f3b',
'facturx'
);
writeFileSync('invoice.pdf', Buffer.from(facturx));
// Download as plain PDF (visual only, no embedded XML)
const pdf = await scell.invoices.download(
'019dfae2-abef-73e4-b6b2-e4cdae938f3b',
'pdf'
);
// Download as raw XML (CII EN16931)
const xml = await scell.invoices.download(
'019dfae2-abef-73e4-b6b2-e4cdae938f3b',
'xml'
);

Supprimer un brouillon

delete.ts
typescript
import { ScellApiClient } from '@scell/sdk';
const scell = new ScellApiClient('sk_live_your_api_key');
// Delete a draft invoice — only 'draft' status allowed
// Returns 422 if invoice is validated/transmitted/paid (ISCA immutability)
await scell.invoices.delete('019dfae2-abef-73e4-b6b2-e4cdae938f3b');

Signatures

7 méthodes

Créez des demandes de signature électronique simple eIDAS EU-SES (le seul niveau exposé par Scell.io). Multi-signataires (1-10), authentification email/SMS/les deux, OTP avec message custom, positions visuelles avec unité percent ou pixel, archivage 10 ans. Le signing_url retourné pointe vers la page wrapper Scell.io (https://sign.scell.io/sign/...) qui embed le page de signature upstream dans une iframe avec branding Scell par défaut. Disponible sur ScellApiClient et ScellTenantClient.

MéthodeDescription
list(options?)Lister les demandes de signature (filtres : status, environment, company_id, sub_tenant_id, per_page max 100). Scopé par tenant via sk_live_* / sk_test_*.
get(id)Obtenir une demande de signature par ID (scope tenant strict, 404 si appartient à un autre tenant)
create(data)Créer une demande de signature eIDAS EU-SES
cancel(id)Annuler une demande de signature en attente
remind(id)Envoyer une relance aux signataires en attente
download(id, type)Télécharger le document signé ou le fichier de preuve
auditTrail(id)Obtenir la piste d'audit complète de la signature
signatures.ts
typescript
import { ScellApiClient } from '@scell/sdk';
const scell = new ScellApiClient('sk_live_your_api_key');
// Read PDF and encode to base64
const pdfBytes = await fs.readFile('contrat.pdf');
const base64Pdf = pdfBytes.toString('base64');
const signature = await scell.signatures.create({
// Required
title: 'Contrat de prestation',
document: base64Pdf,
document_name: 'contrat.pdf',
signers: [
{
first_name: 'Marie',
last_name: 'Dupont',
email: 'marie.dupont@example.com',
auth_method: 'email',
// Custom message with {OTP} placeholder (max 500 chars)
message: 'Bonjour Marie, votre contrat est pret. Code OTP: {OTP}',
},
],
// Optional: where the signature box is dropped on the PDF
signature_positions: [
{ page: 1, x: 70, y: 80, unit: 'percent' }, // unit: 'percent' (default) | 'pixel'
],
// Optional: redirects after signing / cancelling
redirect_complete_url: 'https://yourapp.com/contracts/done',
redirect_cancel_url: 'https://yourapp.com/contracts/cancelled',
// Optional: 10-year eIDAS archiving
archive_enabled: true,
});
console.log(signature.id);
console.log(signature.status); // 'pending' | 'waiting_signers' | ...
console.log(signature.signers[0].signing_url); // https://sign.scell.io/sign/{id}/{signerId}?...&signature=HMAC
// Cancel a signature request
await scell.signatures.cancel(signature.id);
// Send a reminder to pending signers
await scell.signatures.remind(signature.id);
// Download the signed document
const signed = await scell.signatures.download(signature.id, 'signed');
// List signatures — scope automatique au tenant courant via sk_live_* / sk_test_*.
// Filtres disponibles : status, environment ('production' | 'sandbox'), company_id,
// sub_tenant_id (anti-IDOR — limité aux sub_tenants du tenant courant), per_page (max 100).
const pending = await scell.signatures.list({
status: 'pending',
environment: 'production',
sub_tenant_id: '019d5ea8-0000-0000-0000-000000000000',
per_page: 50,
});
// --- Demande de signature au nom d'un sub-tenant (depuis 2026-05-11) ---
// Passer sub_tenant_id dans le payload POST. La company emettrice
// devient la 1re company du sub-tenant. 404 SUB_TENANT_NOT_FOUND si
// le sub_tenant n'appartient pas au tenant courant.
const signatureSub = await scell.signatures.create({
sub_tenant_id: '019d5ea8-0000-0000-0000-000000000000',
title: 'Contrat de prestation',
document: base64Pdf,
document_name: 'contrat.pdf',
signers: [{ first_name: 'Marie', last_name: 'Dupont', email: 'marie@example.com', auth_method: 'email' }],
});

Personnalisation de la page de signature (white-label)

Le payload ui_config (21 champs alignés sur la spec EU-SES eIDAS v1.0.17) et signature_options (4 champs comportementaux) permettent de white-labeler intégralement la page que voient vos signataires. Tout est optionnel : si vous omettez ui_config, le backend applique la palette Scell.io. Si vous fournissez un sous-ensemble, seuls les champs absents sont remplis avec les défauts — vos overrides sont préservés. iframe_ancestors est automatiquement étendu avec https://sign.scell.io et https://scell.io (cap 20, dédupliqué) pour que le wrapper puisse embarquer la page upstream.

ui_config — 21 champs

ChampTypeDescription
Sidebar (4)
sidebar_logoURLLogo affiché dans la sidebar (HTTPS, max 500 chars).
sidebar_background_color#RRGGBBCouleur de fond de la sidebar.
sidebar_title_color#RRGGBBCouleur des titres dans la sidebar.
sidebar_text_color#RRGGBBCouleur du texte dans la sidebar.
Header (3)
header_background_color#RRGGBBCouleur de fond du header.
header_title_color#RRGGBBCouleur du titre principal du header.
header_subtitle_color#RRGGBBCouleur du sous-titre du header.
Footer (1)
footer_background_color#RRGGBBCouleur de fond du footer.
Boutons standards (4)
button_text_color#RRGGBBCouleur du texte des boutons.
button_text_color_hover#RRGGBBCouleur du texte au survol.
button_background_color#RRGGBBCouleur de fond des boutons.
button_background_color_hover#RRGGBBCouleur de fond au survol.
Bouton « Signer » (4) — override des boutons standards
sign_button_text_color#RRGGBBTexte du bouton Signer.
sign_button_text_color_hover#RRGGBBTexte du bouton Signer au survol.
sign_button_background_color#RRGGBBFond du bouton Signer.
sign_button_background_color_hover#RRGGBBFond du bouton Signer au survol.
Toggles d'affichage (4)
hide_sidebarbooleanMasque entièrement la sidebar.
hide_headerbooleanMasque le header.
hide_download_validatedbooleanMasque le bouton de téléchargement après validation OTP.
hide_download_signedbooleanMasque le bouton de téléchargement après signature.
Iframe (1)
iframe_ancestorsURL[]Domaines autorisés à embarquer la page (max 20). Le backend ajoute automatiquement sign.scell.io et scell.io.

signature_options — 4 champs comportementaux

ChampTypeDescription
signature_mode'typed' | 'drawn' | 'both'Mode de saisie de la signature. typed = clavier, drawn = dessinée, both = laisse le signataire choisir.
signer_must_readbooleanForce le signataire à parcourir tout le document avant que le bouton Signer ne soit actif.
user_editable_data{name?, mobile?, email?}Champs que le signataire peut modifier sur ses propres données (booléens par champ).
timezonestringIdentifiant IANA (ex: Europe/Paris). Affecte les horodatages affichés et le PDF audit trail.

Autres champs notables

  • signers[].message (max 500 chars) — message custom envoyé par email/SMS au signataire. Supporte le placeholder {OTP} qui sera remplacé par le code à 6 chiffres.
  • signers[].auth_method = 'email' | 'sms' | 'both' — méthode d'envoi du code OTP. both envoie l'OTP par email ET par SMS (renforce la sécurité).
  • signers[].order — ordre de signature pour le mode séquentiel (1, 2, 3...). Si absent, ordre d'apparition dans le tableau.
  • signature_positions[].unit = 'percent' (défaut) ou 'pixel'. Si pixel, vous pouvez fournir page_width_px / page_height_px pour override la détection auto via parser PDF (fallback A4 595×842).
  • archive_enabled — active l'archivage 10 ans eIDAS conforme.

Signature blocks — paraphe (initiales), mentions juridiques, date

3 blocs optionnels que Scell grave sur le PDF avant envoi au service de signature certifié EU-SES (qui ne supporte pas nativement les mentions). Le PDF original est conservé pour l'audit trail.

initials_blockparaphe automatique multi-pages(positions[] depuis v2.17.0 JS / v2.15.0 PHP / v2.16.0 MCP)
ChampTypeDescription
enabledbooleanActive ou désactive le bloc paraphe.
mode'auto' | 'custom''auto' = initiales depuis nom du 1er signataire ; 'custom' = utilise custom_text.
custom_textstringTexte custom (max 8 chars). Requis si source=custom.
positions[]{page, x, y, ...}[]Nouveau format recommandé. Une entrée par page avec sa propre position (x, y, unit) et ses overrides optionnels (font_size, color, bold). Max 500 entrées. Si fourni, prévaut sur position+pages (legacy).
position{x, y, unit}Legacy. Position commune appliquée à toutes les pages choisies par pages. Ignoré si positions[] est fourni.
pages'all' | 'except_last' | number[]Legacy. Sélecteur de pages pour position commune. Ignoré si positions[] est fourni.
font_sizenumber (6-20)Défaut bloc, surchargeable par positions[].font_size.
color#RRGGBBDéfaut bloc, surchargeable per-position.
boldbooleanDéfaut bloc, surchargeable per-position.
  • mentions[] — tableau de mentions juridiques (max 20). Chaque entrée : {label, signer_index?, position: {page, x, y}, required?, fallback_text?}. Le bloc est gravé directement par Scell (texte du label ou du fallback_text à défaut).
  • date_block — date du jour pré-remplie (timezone IANA). position.page accepte un entier 1-indexé OU la string 'last' (dernière page).
  • Référence complète — voir scell-api-llms.txt section "Signature blocks (v2.12.0)".

Exemple complet — personnalisation white-label + blocs

signatures-full.ts
typescript
// White-label override with ui_config (21 fields) and signature_options.
// Any field omitted falls back to Scell.io defaults.
const signature = await scell.signatures.create({
title: 'Contrat de prestation',
document: base64Pdf,
document_name: 'contrat.pdf',
signers: [
{ first_name: 'Marie', last_name: 'Dupont', phone: '+33612345678', auth_method: 'sms' },
{ first_name: 'Jean', last_name: 'Martin', email: 'jean@example.com', auth_method: 'email', order: 2 },
],
signature_positions: [
{ page: 1, x: 70, y: 80, width: 20, height: 8, unit: 'percent' },
],
ui_config: {
// Sidebar (4)
sidebar_logo: 'https://yourcdn.com/logo.svg',
sidebar_background_color: '#0F172A',
sidebar_title_color: '#FFFFFF',
sidebar_text_color: '#CBD5E1',
// Header (3)
header_background_color: '#FFFFFF',
header_title_color: '#0F172A',
header_subtitle_color: '#475569',
// Footer (1)
footer_background_color: '#F8FAFC',
// Standard buttons (4)
button_text_color: '#FFFFFF',
button_text_color_hover: '#FFFFFF',
button_background_color: '#6366F1',
button_background_color_hover: '#4F46E5',
// Sign button (4) — overrides standard buttons for the Sign action
sign_button_text_color: '#FFFFFF',
sign_button_text_color_hover: '#FFFFFF',
sign_button_background_color: '#10B981',
sign_button_background_color_hover: '#059669',
// Visibility toggles (4)
hide_sidebar: false,
hide_header: false,
hide_download_validated: false,
hide_download_signed: false,
// Iframe ancestors (max 20). Scell auto-injects sign.scell.io + scell.io.
iframe_ancestors: ['https://app.acme.com', 'https://acme.com'],
},
signature_options: {
// 'typed' (keyboard only) | 'drawn' (mouse/finger only) | 'both' (signer chooses)
signature_mode: 'both',
// Force scrolling through the entire document before sign button enables
signer_must_read: true,
// Per-field control over what the signer can edit on their own data
user_editable_data: { name: false, mobile: true, email: false },
// IANA timezone identifier
timezone: 'Europe/Paris',
},
// Initials block — paraphe burned by Scell on each page BEFORE forwarding
// to the certified EU-SES signature service. Two formats accepted (v2.17.0+):
//
// 1. NEW — positions[] (one entry per page, recommended for multi-page)
// 2. LEGACY — position + pages (same position on all pages)
//
// If both are provided, positions[] wins.
initials_block: {
enabled: true,
mode: 'auto', // 'auto' (initials from signer name) | 'custom'
source: 'signer_name',
font_size: 10, // block default (overridable per-position)
color: '#1a1a1a', // block default (overridable per-position)
bold: false, // block default (overridable per-position)
positions: [
{ page: 1, x: 90, y: 90, unit: 'percent' },
{ page: 2, x: 88, y: 92, unit: 'percent', font_size: 12 },
{ page: 3, x: 85, y: 90, unit: 'percent', color: '#aa0000' },
],
},
// Mentions — legal mentions burned on the PDF (max 20)
mentions: [
{
label: 'Lu et approuvé',
required: true,
signer_index: 0,
position: { page: 1, x: 10, y: 80, unit: 'percent' },
font_size: 9,
color: '#333333',
},
],
// Date block — today's date in the tenant timezone
date_block: {
enabled: true,
format: 'dd/MM/yyyy',
timezone: 'Europe/Paris',
position: { page: 'last', x: 70, y: 88, unit: 'percent' },
font_size: 9,
color: '#555555',
},
redirect_complete_url: 'https://yourapp.com/contracts/done',
redirect_cancel_url: 'https://yourapp.com/contracts/cancelled',
expires_at: '2026-12-31T23:59:59Z',
archive_enabled: true,
external_id: 'CRM-INV-2026-0042',
});

Avoirs

8 méthodes

Créez des avoirs liés à des factures existantes. Supporte les remboursements partiels et totaux. Disponible sur ScellApiClient.

MéthodeDescription
list(options?)Lister les avoirs avec pagination et filtres
get(id)Obtenir un avoir par UUID
create(data)Créer un avoir lié à une facture
update(id, data)Mettre à jour un avoir en brouillon
delete(id)Supprimer un avoir en brouillon (ISCA : draft uniquement)
send(id)Envoyer l'avoir au destinataire (irréversible)
download(id)Télécharger l'avoir en PDF
remainingCreditable(invoiceId)Montant restant créditable d'une facture
credit-notes.ts
typescript
import { ScellApiClient } from '@scell/sdk';
const scell = new ScellApiClient('sk_live_your_api_key');
// ── Total credit note (refund entire invoice) ───────────────────────
const { data: totalCN } = await scell.creditNotes.create({
invoice_id: '019dfae2-abef-73e4-b6b2-e4cdae938f3b',
reason: 'Annulation de la prestation',
type: 'total',
});
// totalCN.status === 'draft'
// totalCN.credit_note_number === 'AVO-2026-000005'
// ── Partial credit note (specific lines) ────────────────────────────
const { data: partialCN } = await scell.creditNotes.create({
invoice_id: '019dfae2-abef-73e4-b6b2-e4cdae938f3b',
reason: 'Remboursement partiel — 2 articles retournés',
type: 'partial',
items: [
{
invoice_line_id: '019dfae2-bbbb-0000-0000-000000000001',
quantity: 2, // credit 2 of original quantity
},
],
});
// ── Check remaining creditable amount ───────────────────────────────
const { data: remaining } = await scell.creditNotes.remainingCreditable(
'019dfae2-abef-73e4-b6b2-e4cdae938f3b'
);
// remaining.total_ht, remaining.total_ttc, remaining.lines[]
// ── Update a draft credit note ──────────────────────────────────────
const { data: updated } = await scell.creditNotes.update(partialCN.id, {
reason: 'Remboursement partiel — 3 articles retournés (corrigé)',
});
// ── Send credit note (irreversible — enters ISCA chain) ─────────────
await scell.creditNotes.send(partialCN.id);
// ── Download as PDF ─────────────────────────────────────────────────
const pdf = await scell.creditNotes.download(partialCN.id);
// ── Delete a draft (only draft status — ISCA compliance) ────────────
await scell.creditNotes.delete(totalCN.id);
// ── List with filters ───────────────────────────────────────────────
const { data: list, meta } = await scell.creditNotes.list({
status: 'draft',
per_page: 25,
});

Entreprises

7 méthodes

Gérez les entités entreprises avec leurs informations légales (SIREN, numéro TVA, adresse). Inclut le flux de vérification KYC/KYB. Disponible sur ScellClient (Bearer token).

MéthodeDescription
list()Lister toutes les entreprises de l'utilisateur authentifié
get(id)Obtenir une entreprise par ID
create(data)Enregistrer une nouvelle entreprise avec ses données légales
update(id, data)Mettre à jour les informations de l'entreprise
delete(id)Supprimer une entreprise
initiateKyc(id)Démarrer le processus de vérification KYC/KYB
kycStatus(id)Vérifier le statut actuel de la vérification KYC
companies.ts
typescript
import { ScellClient } from '@scell/sdk';
const client = new ScellClient('your_bearer_token');
// Create a company
const company = await client.companies.create({
name: 'ACME Corp',
siren: '123456789',
vat_number: 'FR12345678901',
address: {
street: '10 Rue de la Paix',
city: 'Paris',
postal_code: '75002',
country: 'FR',
},
});
// List all companies
const companies = await client.companies.list();
// Update a company
await client.companies.update(company.id, { name: 'ACME Corp Updated' });
// Initiate KYC/KYB verification
await client.companies.initiateKyc(company.id);
// Check KYC status
const kyc = await client.companies.kycStatus(company.id);
console.log(kyc.status); // 'pending' | 'approved' | 'rejected'

Clés API

4 méthodes

Créez et gérez des clés API pour l'authentification serveur à serveur. Les clés peuvent être live (sk_live_*) ou sandbox (sk_test_*). La valeur de la clé secrète n'est affichée qu'une seule fois à la création. Disponible sur ScellClient (Bearer token).

MéthodeDescription
list()Lister toutes les clés API du compte
get(id)Obtenir une clé API par ID (valeur masquée)
create(data)Créer une nouvelle clé API (environnement live ou test)
delete(id)Révoquer et supprimer une clé API
api-keys.ts
typescript
import { ScellClient } from '@scell/sdk';
const client = new ScellClient('your_bearer_token');
// Create a new API key
const key = await client.apiKeys.create({
name: 'Production Key',
environment: 'live', // 'live' | 'test'
});
console.log(key.id);
console.log(key.key); // sk_live_... (shown only once)
// List all API keys
const keys = await client.apiKeys.list();
// Delete an API key
await client.apiKeys.delete(key.id);

Webhooks

8 méthodes

Gérez les endpoints webhook pour recevoir des notifications en temps réel. Chaque webhook possède un secret de signature (wh_sec_*) pour la vérification HMAC-SHA256. Supporte le filtrage d'événements, les tests et les journaux de livraison. Disponible sur ScellClient (Bearer token).

MéthodeDescription
list()Lister tous les endpoints webhook
get(id)Obtenir les détails d'un webhook par ID
create(data)Créer un endpoint webhook avec abonnements aux événements
update(id, data)Mettre à jour l'URL, les événements ou le statut actif
delete(id)Supprimer un endpoint webhook
test(id)Envoyer un payload de test à l'URL du webhook
regenerateSecret(id)Régénérer le secret de signature du webhook (wh_sec_…)
logs(id)Voir les journaux de livraison et codes de réponse
webhooks.ts
typescript
import { ScellClient } from '@scell/sdk';
const client = new ScellClient('your_bearer_token');
// Create a webhook endpoint
const webhook = await client.webhooks.create({
url: 'https://yourapp.com/webhooks/scell',
events: [
'invoice.created',
'invoice.validated',
'signature.completed',
'balance.low',
],
active: true,
});
console.log(webhook.id);
console.log(webhook.secret); // wh_sec_... (for signature verification)
// List all webhooks
const list = await client.webhooks.list();
// Update a webhook
await client.webhooks.update(webhook.id, {
events: ['invoice.created', 'signature.completed'],
});
// Test a webhook (sends a test payload)
await client.webhooks.test(webhook.id);
// Regenerate the signing secret
const newSecret = await client.webhooks.regenerateSecret(webhook.id);
// View delivery logs
const logs = await client.webhooks.logs(webhook.id);
// Delete a webhook
await client.webhooks.delete(webhook.id);

Conformité fiscale

26 méthodes

Suite complète de conformité fiscale ISCA autocertifiée (article 286-I-3° bis CGI). Ledger increvable depuis v0.6.0 : chaînes ISCA isolées par paire (tenant_id, sub_tenant_id), triggers PostgreSQL en défense en profondeur, chaîne SHA-256, clôtures journalières/mensuelles/annuelles (1 par tenant + 1 par sub_tenant actif), ancrage TSA RFC 3161 + ancrage blockchain Bitcoin gratuit via OpenTimestamps (best effort), export FEC, kill switch d'arrêt d'urgence, moteur de règles, health check intégrité (gaps, orphans, chain_invalid) et auto-attestation ISCA nominative par tenant ou sub_tenant. Disponible sur ScellApiClient et ScellTenantClient.

MéthodeDescription
compliance()Obtenir le statut global de conformité fiscale (ISCA)
entries()Lister les entrées du registre immuable SHA-256
closings()Lister les clôtures journalières et mensuelles
dailyClosing()Déclencher une clôture journalière immédiate
integrity()Lancer une vérification complète de la chaîne de hachage
integrityHistory()Obtenir l'historique de toutes les vérifications d'intégrité
integrityForDate(date)Vérifier l'intégrité pour une date précise
rules()Lister toutes les règles d'automatisation fiscale
createRule(data)Créer une règle fiscale (clé, valeur, description)
updateRule(id, data)Mettre à jour une règle fiscale existante
ruleDetail(key)Obtenir les détails d'une règle fiscale par clé
ruleHistory(key)Obtenir l'historique des modifications d'une règle
exportRules()Exporter toutes les règles fiscales en fichier téléchargeable
replayRules()Rejouer toutes les règles fiscales (recalculer les données dérivées)
anchors()Lister les ancres de timestamping TSA RFC 3161
killSwitchStatus()Obtenir le statut du kill switch (arrêt d'urgence)
activateKillSwitch()Activer le kill switch (suspend toutes les opérations fiscales)
deactivateKillSwitch()Désactiver le kill switch (reprendre les opérations)
fecExport()Générer l'export FEC pour les autorités fiscales françaises
forensicExport()Générer un export forensique avec données d'audit complètes
attestation(year)Obtenir l'attestation de conformité ISCA pour une année
attestationDownload(year)Télécharger le PDF de l'attestation pour une année
iscaSelfAttestationDownload(subTenantId?)Télécharger l'auto-attestation ISCA NOMINATIVE (PDF) pour le tenant ou un sub_tenant — depuis v1.17.0 (JS) / v1.16.0 (PHP)
iscaMeasuresRegisterDownload()Télécharger le registre des mesures ISCA (PDF non-nominatif)
iscaTechnicalDossierDownload()Télécharger le dossier technique ISCA conforme NF Z 42-025 (PDF non-nominatif)
integrityStatus()Statut résumé de l'intégrité du ledger (gaps, orphans, chain_invalid) — endpoint /api/v1/fiscal/integrity
fiscal.ts
typescript
import { ScellApiClient } from '@scell/sdk';
const scell = new ScellApiClient('sk_live_your_api_key');
// ─── Compliance overview ───────────────────────────────
const status = await scell.fiscal.compliance();
console.log(status.is_compliant); // true | false
console.log(status.isca_status);
// ─── Immutable ledger entries ──────────────────────────
const entries = await scell.fiscal.entries();
// ─── Closings ──────────────────────────────────────────
const closings = await scell.fiscal.closings();
await scell.fiscal.dailyClosing(); // Trigger a daily closing
// ─── Integrity verification ───────────────────────────
const integrity = await scell.fiscal.integrity();
const history = await scell.fiscal.integrityHistory();
const forDate = await scell.fiscal.integrityForDate('2026-03-30');
// ─── Fiscal rules engine ──────────────────────────────
const rules = await scell.fiscal.rules();
const newRule = await scell.fiscal.createRule({
key: 'auto_daily_closing',
value: true,
description: 'Automatically trigger daily closings at midnight',
});
await scell.fiscal.updateRule(newRule.id, { value: false });
const detail = await scell.fiscal.ruleDetail('auto_daily_closing');
const ruleHist = await scell.fiscal.ruleHistory('auto_daily_closing');
await scell.fiscal.exportRules();
await scell.fiscal.replayRules();
// ─── TSA Anchors ──────────────────────────────────────
const anchors = await scell.fiscal.anchors();
// ─── Kill switch ──────────────────────────────────────
const ksStatus = await scell.fiscal.killSwitchStatus();
await scell.fiscal.activateKillSwitch();
await scell.fiscal.deactivateKillSwitch();
// ─── Exports ──────────────────────────────────────────
const fec = await scell.fiscal.fecExport();
const forensic = await scell.fiscal.forensicExport();
const attestation = await scell.fiscal.attestation(2026);
const download = await scell.fiscal.attestationDownload(2026);
// ─── ISCA self-attestation (NOMINATIVE — depuis v1.17.0) ──
// Auto-attestation pour le tenant courant (donnees KYB)
const tenantPdf = await scell.fiscal.iscaSelfAttestationDownload();
fs.writeFileSync('attestation-tenant.pdf', Buffer.from(tenantPdf));
// Auto-attestation pour un sub_tenant specifique
const subPdf = await scell.fiscal.iscaSelfAttestationDownload('019d5ea8-...');
fs.writeFileSync('attestation-sub-tenant.pdf', Buffer.from(subPdf));
// Documents de conformite (non-nominatifs)
const measures = await scell.fiscal.iscaMeasuresRegisterDownload();
const dossier = await scell.fiscal.iscaTechnicalDossierDownload();

Statistiques

2 méthodes

Obtenez des statistiques agrégées et mensuelles pour les factures, signatures et revenus. Disponible sur ScellApiClient et ScellTenantClient.

MéthodeDescription
overview()Obtenir les statistiques agrégées (factures, signatures, revenus)
monthly()Obtenir la ventilation mois par mois de l'activité et des revenus
stats.ts
typescript
import { ScellApiClient } from '@scell/sdk';
const scell = new ScellApiClient('sk_live_your_api_key');
// Get overview statistics
const overview = await scell.stats.overview();
console.log(overview.total_invoices);
console.log(overview.total_signatures);
console.log(overview.total_revenue);
// Get monthly breakdown
const monthly = await scell.stats.monthly();
monthly.forEach(m => {
console.log(m.month, m.invoices_count, m.revenue);
});

Facturation, solde & recharge

8 méthodes

Point d'entrée unique pour la facturation Scell.io — depuis v2.2.0 cette ressource remplace l'ancien BalanceResource (supprimé : les endpoints /api/v1/balance/* renvoient 404). Couvre le solde courant (usage()), la recharge Stripe (topUp() + confirmTopUp()), l'historique des transactions (transactions()), la liste des factures Scell.io émises au tenant (invoices()) et le paiement en ligne d'une facture (payInvoice() → PaymentIntent Stripe). Disponible sur ScellApiClient et ScellTenantClient.

MéthodeDescription
invoices()Lister toutes les factures de facturation Scell.io
showInvoice(id)Obtenir les détails d'une facture de facturation
downloadInvoice(id)Télécharger une facture de facturation en PDF
usage()Obtenir les métriques d'utilisation de la période en cours
topUp(data)Initier une recharge de crédits
confirmTopUp(data)Confirmer une recharge en attente avec le code de confirmation
payInvoice(id)Initier le paiement Stripe d'une facture Scell.io (PaymentIntent + client_secret pour Stripe.js)
transactions()Lister toutes les transactions de facturation
billing.ts
typescript
import { ScellApiClient } from '@scell/sdk';
const scell = new ScellApiClient('sk_live_your_api_key');
// List billing invoices
const invoices = await scell.billing.invoices();
// Get a specific billing invoice
const inv = await scell.billing.showInvoice('billing_inv_id');
// Download billing invoice PDF
const pdf = await scell.billing.downloadInvoice('billing_inv_id');
// Get current usage metrics
const usage = await scell.billing.usage();
console.log(usage.invoices_used);
console.log(usage.signatures_used);
console.log(usage.credits_remaining);
// Top up credits
await scell.billing.topUp({ amount: 100, payment_method: 'card' });
// Confirm a pending top-up
await scell.billing.confirmTopUp({ top_up_id: 'tu_id', confirmation_code: '1234' });
// Pay a Scell.io billing invoice (depuis v2.2.0 - Wave 6 2026-05-10)
// Initiates a Stripe PaymentIntent. Use the client_secret with Stripe.js
// to complete the payment client-side; webhook marks invoice as paid.
const intent = await scell.billing.payInvoice('billing_inv_id');
console.log(intent.clientSecret); // Pass to stripe.confirmCardPayment()
console.log(intent.paymentIntentId); // pi_xxx
console.log(intent.amount); // amount in cents (EUR)
console.log(intent.status); // requires_payment_method | requires_confirmation
// List billing transactions
const transactions = await scell.billing.transactions();

Authentification & Gestion Tenant

15 méthodes

Inscription / connexion utilisateur dashboard ET gestion du compte tenant partenaire. Inclut la création de clés sk_* / pk_*, la mise à jour du profil + Company "self" (logo, IBAN, mentions Factur-X), l'upload du logo via S3 presigned. Disponible sur ScellClient (Bearer Sanctum) et ScellTenantClient.

MéthodeDescription
register(data)Inscription d'un nouvel utilisateur dashboard
login(data)Connexion (Bearer token Sanctum)
logout()Déconnexion + révocation du token
me()Obtenir le profil de l'utilisateur connecté
forgotPassword(email)Envoyer un email de réinitialisation
resetPassword(token, password)Réinitialiser le mot de passe avec le token reçu par email
tenantLogin(data)Connexion tenant partenaire (séparé du dashboard utilisateur)
tenantRegister(data)Inscription tenant partenaire
tenantMe()Profil du tenant courant
tenantLogout()Déconnexion tenant + révocation du token
tenantKeys()Lister les clés (sk_/pk_) du tenant
createSecretKey()Créer une nouvelle clé secrète tenant (sk_live_* / sk_test_*)
createPublishableKey()Créer une clé publishable tenant (pk_live_* / pk_test_*)
updateTenantProfile(data)Mettre à jour le profil tenant + Company "self" (logo, IBAN, mentions Factur-X)
logoUploadUrl()Obtenir une URL S3 presigned pour uploader le logo de la Company self
regenerateApiKey()Régénérer la clé API tenant

Factures Sub-Tenant (directes)

14 méthodes

Émission de factures Factur-X / UBL / CII au nom d'un sub_tenant (B2B2B). Inclut validation Schematron, soumission PDP/Peppol, envoi email, téléchargement scopé, opérations en lot, et accès au solde encore créditable. Disponible sur ScellApiClient (sk_*) et ScellTenantClient (tk_*).

MéthodeDescription
list(subTenantId, options?)Lister les factures d'un sub_tenant
get(id)Obtenir une facture par UUID
create(subTenantId, data)Créer une facture au nom d'un sub_tenant
update(id, data)Mettre à jour une facture en brouillon
delete(id)Supprimer une facture en brouillon
submit(id)Soumettre la facture au réseau PDP/Peppol
validate(id)Valider la facture sans la soumettre (Schematron Factur-X)
send(id, data?)Envoyer la facture par email au buyer
download(id, format?)Télécharger en facturx | pdf | xml
downloadForSubTenant(subTenantId, id, format?)Téléchargement scopé sub_tenant strict
remainingCreditable(id)Solde encore créditable de la facture
bulkCreate(subTenantId, data[])Créer plusieurs factures en lot
bulkSubmit(ids[])Soumettre plusieurs factures au PDP en lot
bulkStatus(ids[])Statut courant de plusieurs factures

Factures entrantes (Sub-Tenant)

8 méthodes

Gestion des factures reçues par un sub_tenant via le réseau PDP — flux complet accept / reject / dispute / mark-paid. Permet aussi d'enregistrer manuellement une facture reçue hors PDP (papier, email, etc.).

MéthodeDescription
create(subTenantId, data)Enregistrer une facture entrante reçue hors PDP (saisie manuelle)
listForSubTenant(subTenantId, options?)Lister les factures entrantes d'un sub_tenant
get(id)Obtenir une facture entrante par UUID
accept(id, data?)Accepter une facture entrante (PDP)
reject(id, reason)Rejeter une facture entrante avec motif
markPaid(id, data?)Marquer comme payée (date, référence)
delete(id)Supprimer une facture entrante en brouillon
download(id, format?)Télécharger la facture entrante (facturx | pdf | xml)

Avoirs Tenant (multi sub_tenants)

8 méthodes

Avoirs émis pour le compte d'un sub_tenant. Conserve l'héritage strict des champs buyer/seller depuis la facture associée (compliance ISCA — pas d'override possible).

MéthodeDescription
list(options?)Lister tous les avoirs du tenant + sub_tenants
get(id)Obtenir un avoir par UUID
create(data)Créer un avoir lié à une facture
update(id, data)Mettre à jour un avoir en brouillon
delete(id)Supprimer un avoir en brouillon
send(id, data?)Envoyer l'avoir par email
download(id, format?)Télécharger en facturx | pdf | xml
remainingCreditable(invoiceId)Solde encore créditable d'une facture

Templates de facture

7 méthodes

Personnalisation des PDF Factur-X : logo, couleurs, footer, mentions légales. Cascade explicite > sub_tenant default > tenant default > system default. Cache Redis 5 min.

MéthodeDescription
list(options?)Lister les templates (system / tenant / sub_tenant scope)
get(id)Obtenir un template par UUID
create(data)Créer un template personnalisé (logo, couleurs, mentions)
update(id, data)Mettre à jour un template
delete(id)Supprimer un template
markDefault(id)Marquer un template comme défaut (PUT /:id/default)
uploadLogo(id, file)Uploader un logo pour le template (multipart)

Acheteurs (registre)

5 méthodes

Registre d'acheteurs réutilisables, scopé strictement par (tenant_id, sub_tenant_id). Référencer un buyer via buyer_id dans la création de facture pour éviter de re-saisir les données. Supporte B2B (SIRET/SIREN/TVA) et B2C (particulier is_individual=true) + adresse de livraison BG-13.

MéthodeDescription
list(options?)Lister les acheteurs du registre (paginé, filtres q / is_individual)
get(id)Obtenir un acheteur par UUID
create(data)Enregistrer un nouvel acheteur (B2B SIRET ou B2C particulier)
update(id, data)Mettre à jour les données d'un acheteur (PATCH)
delete(id)Supprimer un acheteur (soft delete)
resolveVatContext(data)Pré-résoudre le contexte TVA d'une ligne (taux, catégorie, code EN16931, exemption_reason, justification CGI)
buyers.ts
typescript
import { ScellApiClient } from '@scell/sdk';
const scell = new ScellApiClient('sk_live_your_api_key');
// Create a B2B buyer (French company — SIRET required)
const buyer = await scell.buyers.create({
name: 'GN IMMO',
is_individual: false,
siret: '49438068600076',
vat_number: 'FR42494380686',
email: 'contact@gnimmo.com',
country: 'FR',
billing_address: {
line1: '453 Route Nationale 7',
postal_code: '13670',
city: 'Verquières',
country: 'FR',
},
});
// Create a B2C buyer (individual — no SIRET/VAT)
const individual = await scell.buyers.create({
name: 'Marie Dupont',
is_individual: true,
email: 'marie.dupont@gmail.com',
country: 'FR',
billing_address: {
line1: '12 Rue des Lilas',
postal_code: '75011',
city: 'Paris',
country: 'FR',
},
});
// Use buyer_id when creating invoices (auto-snapshot)
const invoice = await scell.invoices.create({
buyer_id: buyer.id,
due_date: '2026-07-15',
lines: [
{ description: 'Consulting', quantity: 1, unit_price: 2500, tax_rate: 20 },
],
});

TVA automatique (vat-context)

1 méthode

POST /api/v1/tenant/buyers/vat-context pré-résout le contexte TVA d'une ligne de facture avant émission : taux applicable, catégorie EN16931 (S, AE, O, Z, E), exemption_reason et justification CGI (art. 259, 259-1, 259-2, 259 A). Couvre FR→FR, FR→UE B2B (autoliquidation), FR→UE B2C, FR→hors UE (export) et l'override art. 259 A via place_of_supply (services immobiliers, restauration, événementiel). Si line.tax_rate est fourni, retourne aussi des warnings de cohérence (mismatch, catégorie incohérente, etc.).

Catégorie TVATaux par défaut FREN16931Usage
STANDARD20 %STaux normal (art. 278 CGI)
INTERMEDIATE10 %STaux intermédiaire (restauration, transport)
REDUCED5,5 %STaux réduit (alimentation, livres)
SUPER_REDUCED2,1 %STaux super-réduit (médicaments)
ZERO_RATED0 %ZTaux zéro (exports hors UE)
EXEMPTEOpération exonérée (médical, financier)
REVERSE_CHARGE0 %AEAutoliquidation UE B2B (art. 259-1 CGI)
OUT_OF_SCOPEOHors champ (export hors UE)
Règles de résolution (cascade)
  • R1FR→FR (entreprise ou particulier) : TVA française selon la catégorie (art. 278+ CGI).
  • R2FR→UE entreprise avec vat_number_valid : REVERSE_CHARGE (art. 259-1 CGI, autoliquidation).
  • R3FR→UE entreprise SANS vat_number ou particulier : TVA française (art. 259-2 lieu prestataire).
  • R4FR→hors UE : OUT_OF_SCOPE (export, hors champ TVA).
  • R6Override 259 A : si place_of_supply ≠ pays buyer, applique la TVA du pays lieu de prestation (immobilier, restauration, événementiel en France).

Articles CGI : art. 259, art. 259-1, art. 259-2, art. 259 A.

vat-context.ts
typescript
import { ScellApiClient } from '@scell/sdk';
const scell = new ScellApiClient('sk_live_your_api_key');
// ---------------------------------------------------------------------------
// Mode 1 — Acheteur déjà enregistré dans le registre (buyer_id)
// ---------------------------------------------------------------------------
// Pré-résout le contexte TVA pour une ligne STANDARD (20 % par défaut FR→FR).
// Le sub-tenant (s'il existe) est résolu côté serveur depuis la clé d'API.
const fr = await scell.buyers.resolveVatContext({
buyer_id: '019cb416-b6db-730c-b3a5-f8b7a4512eb1',
line: {
category: 'STANDARD',
place_of_supply: 'FR',
},
});
console.log(fr.resolution);
// {
// rate: 20,
// category: 'STANDARD',
// en16931_code: 'S',
// exemption_reason: null,
// justification: 'TVA française standard (art. 278 CGI)',
// is_auto_resolved: true,
// rule: 'R1_fr_domestic'
// }
// ---------------------------------------------------------------------------
// Mode 2 — Acheteur inline (B2B UE avec numéro de TVA vérifié VIES)
// ---------------------------------------------------------------------------
// Autoliquidation (reverse charge) déclenchée automatiquement par la règle R2.
const ue = await scell.buyers.resolveVatContext({
buyer: {
country: 'DE',
is_individual: false,
vat_number: 'DE123456789',
vat_number_valid: true, // typiquement validé via VIES en amont
},
line: { category: 'STANDARD' },
});
console.log(ue.resolution);
// {
// rate: 0,
// category: 'REVERSE_CHARGE',
// en16931_code: 'AE',
// exemption_reason: 'reverse_charge',
// justification: 'TVA non applicable, art. 259-1 du CGI (autoliquidation)',
// is_auto_resolved: true,
// rule: 'R2_eu_b2b_vat_valid'
// }
// ---------------------------------------------------------------------------
// Mode 3 — B2C UE sans numéro de TVA (TVA française restante)
// ---------------------------------------------------------------------------
// Règle R3 : pas de numéro de TVA valide → TVA du prestataire (art. 259-2 CGI).
const b2cUe = await scell.buyers.resolveVatContext({
buyer: {
country: 'IT',
is_individual: true, // particulier italien
},
line: { category: 'STANDARD' },
});
console.log(b2cUe.resolution.rate); // 20 (TVA française)
console.log(b2cUe.resolution.rule); // 'R3_eu_b2c_no_vat'
// ---------------------------------------------------------------------------
// Mode 4 — Override art. 259 A CGI via place_of_supply
// ---------------------------------------------------------------------------
// Service immobilier rendu en France à un client UE → TVA française même
// si le buyer a un numéro de TVA valide (lieu de prestation = France).
const immo = await scell.buyers.resolveVatContext({
buyer: {
country: 'DE',
is_individual: false,
vat_number: 'DE123456789',
vat_number_valid: true,
},
line: {
category: 'STANDARD',
place_of_supply: 'FR', // override 259 A : lieu du bien immobilier
service_nature: 'real_estate_service',
},
});
console.log(immo.resolution.rate); // 20 (TVA française appliquée)
console.log(immo.resolution.rule); // 'R6_place_of_supply_override'
// ---------------------------------------------------------------------------
// Warnings — incohérence détectée si line.tax_rate est fourni
// ---------------------------------------------------------------------------
const check = await scell.buyers.resolveVatContext({
buyer_id: '019cb416-b6db-730c-b3a5-f8b7a4512eb1',
line: {
category: 'STANDARD',
tax_rate: 10, // valeur saisie par l'utilisateur, à valider
},
});
if (check.warnings.length > 0) {
console.warn('Incohérence TVA détectée :', check.warnings);
// [{ code: 'VAT_RATE_MISMATCH', expected: 20, actual: 10,
// message: 'Le taux saisi diffère du taux résolu (R1_fr_domestic).' }]
}

Devis

15 méthodes

Cycle complet : création, envoi par email avec lien public signable, signature canvas, conversion en factures d'acompte (type 386) et de solde (type 380 + BG-22). Numérotation DEV-YYYY-NNNN indépendante de la chaîne ISCA. Disponible sur ScellApiClient.

MéthodeDescription
list(options?)Lister les devis avec pagination et filtres
get(id)Obtenir un devis par UUID
create(data)Créer un devis (numérotation DEV-YYYY-NNNN auto)
update(id, data)Mettre à jour un devis en brouillon
delete(id)Supprimer un devis en brouillon
send(id)Envoyer le devis par email au client (lien public signable)
cancel(id)Annuler un devis envoyé
duplicate(id)Dupliquer un devis existant (nouveau brouillon)
convertToDeposit(id, data)Convertir en facture d'acompte (type 386, TVA immédiate)
convertToBalance(id)Convertir en facture de solde (type 380 + BG-22 auto)
auditLog(id)Piste d'audit append-only (hash SHA-256)
regeneratePublicLink(id)Régénérer le lien public signable (token 90j)
revokePublicLink(id)Révoquer le lien public
pdf(id)Télécharger le devis en PDF
preview(id)Prévisualiser le rendu PDF (sans persister)
quotes.ts
typescript
import { ScellApiClient } from '@scell/sdk';
const scell = new ScellApiClient('sk_live_your_api_key');
// ── Create a quote with signature ───────────────────────────────────
const { data: quote } = await scell.quotes.create({
issue_date: '2026-06-01',
expiration_date: '2026-09-01', // optional, defaults to +90 days
currency: 'EUR',
title: 'Proposition commerciale — Audit digital',
description: 'Prestation complète d\'audit et accompagnement.',
// Buyer (flat fields or buyer_id)
buyer_name: 'GN IMMO',
buyer_siret: '49438068600076',
buyer_country: 'FR',
buyer_email: 'contact@gnimmo.com',
buyer_address: {
line1: '453 Route Nationale 7',
postal_code: '13670',
city: 'Verquières',
country: 'FR',
},
// Signature options
signature_required: true,
// Callback URL — buyer is redirected here after accept/refuse
callback_url: 'https://myapp.com/quotes/callback',
// Lines
lines: [
{
description: 'Audit transformation digitale',
detail: 'Analyse SI existant + recommandations (5 jours)',
quantity: 5,
unit: 'jour',
unit_price_ht: 800.00,
tax_rate: 20.0,
},
{
description: 'Accompagnement mensuel',
quantity: 3,
unit: 'mois',
unit_price_ht: 1200.00,
tax_rate: 20.0,
},
],
});
// quote.quote_number === 'DEV-2026-000012'
// quote.status === 'draft'
// quote.public_url === 'https://scell.io/q/{token}'
// ── Send by email (generates public signable link) ──────────────────
await scell.quotes.send(quote.id);
// ── Duplicate a quote ───────────────────────────────────────────────
const { data: copy } = await scell.quotes.duplicate(quote.id);
// ── Convert accepted quote to deposit invoice (type 386) ────────────
const { data: deposit } = await scell.quotes.convertToDeposit(quote.id, {
amount: 2000.00, // or use percent: 30
});
// deposit.invoice_type === 'deposit'
// deposit.invoice_number === 'FAC-2026-000043'
// ── Convert to balance invoice (type 380 + BG-22 auto-deduction) ────
const { data: balance } = await scell.quotes.convertToBalance(quote.id);

Échéancier de paiement

7 méthodes

Sous-resource d'un devis : gérez les lignes d'échéancier (acomptes planifiés). Chaque ligne peut être convertie individuellement en facture d'acompte. Accès via client.quotes.paymentSchedule (JS) ou $client->quotes()->paymentSchedule() (PHP).

MéthodeDescription
get(quoteId)Lister les lignes d'échéancier du devis
set(quoteId, lines)Remplacer tout l'échéancier (atomique)
patch(quoteId, lines)Mettre à jour partiellement (ajouter/modifier des lignes)
delete(quoteId)Supprimer toutes les lignes (bloqué si facturées)
summary(quoteId)Résumé agrégé : total, facturé, restant, lignes avec statut
convertLine(quoteId, lineId, data)Facturer une ligne spécifique (acompte depuis l'échéancier)
presets()Lister les modèles d'échéancier prédéfinis

Onboarding & Widget

6 méthodes

Deux flows distincts : OAuth Authorization Code server-to-server (créer une session, récupérer l'URL d'autorisation SuperPDP, échanger le code) ET widget public avec clé pk_* (lookup Sirene, création SubTenant). Le widget v3 inverse le flow Scell-first puis SuperPDP — voir Swagger UI.

MéthodeDescription
createSession(data)Créer une session d'onboarding partenaire (mode server-to-server)
getSession(sessionId)Récupérer le statut courant d'une session
getSuperPDPAuthorizeUrl(sessionId)Obtenir l'URL OAuth SuperPDP avec PKCE + state CSRF
superpdpCallback(sessionId, code, state)Échanger un authorization code SuperPDP contre des credentials tenant
lookupSirene(siret)Lookup Sirene par SIRET (auth pk_*) — retourne CompanyData ou manual_entry
createSubTenant(data)Créer un sub_tenant depuis les données du widget (auth pk_*)

Tarification

3 méthodes

Cascade fonctionnelle : tarifs globaux Scell.io → override par tenant (admin uniquement). Le snapshot est figé dans tenant_invoices.metadata['pricing_snapshot'] au moment de la génération de la facture.

MéthodeDescription
getPublic()Obtenir les tarifs publics (sans auth) — affichage marketing
get()Obtenir les tarifs effectifs du tenant (cascade : global → override tenant)
getForTenant()Variant tenant-scopé — alias de get() côté ScellTenantClient

Sous-tenants

7 méthodes

Gérez les sous-tenants pour les plateformes partenaires multi-tenant. Chaque sous-tenant obtient sa propre clé tenant (tk_live_*) et peut être identifié par votre système d'ID externe. Disponible sur ScellApiClient et ScellTenantClient.

MéthodeDescription
list(options?)Lister tous les sous-tenants (paginé)
get(id)Obtenir les détails d'un sous-tenant par ID
create(data)Créer un sous-tenant avec les données de l'entreprise
update(id, data)Mettre à jour les informations d'un sous-tenant
delete(id, options?)Supprimer un sous-tenant. `options.cascade=true` pour cascade Companies. Retourne 422 SUB_TENANT_HAS_FISCAL_ENTRIES si factures émises (compliance ISCA)
findByExternalId(externalId)Rechercher un sous-tenant par votre ID externe
statsOverview(id)Obtenir les statistiques d'utilisation d'un sous-tenant
getSuperPDPStatus(id)Statut SuperPDP courant + recommended_action i18n (cached)
refreshSuperPDPStatus(id)Forcer un poll frais du statut SuperPDP. 422 MISSING_ACCESS_TOKEN inclut authorize_url
superpdpAuthorize(id)Générer une URL OAuth SuperPDP (lancer/relancer le tunnel). Retourne `{ authorize_url, state }`
getResumeUrl(id)Régénérer une URL signée 7j pour reprendre le tunnel d'onboarding
sub-tenants.ts
typescript
import { ScellApiClient } from '@scell/sdk';
const scell = new ScellApiClient('sk_live_your_api_key');
// Create a sub-tenant
const tenant = await scell.subTenants.create({
name: 'Partner Corp',
external_id: 'partner-001',
email: 'admin@partner-corp.com',
company: {
name: 'Partner Corp',
siren: '111222333',
address: {
street: '20 Boulevard Haussmann',
city: 'Paris',
postal_code: '75009',
country: 'FR',
},
},
});
console.log(tenant.id);
console.log(tenant.tenant_key); // sk_live_... (cle secrete sk_*, pas de format tk_*)
// List all sub-tenants
const list = await scell.subTenants.list();
// Get a specific sub-tenant
const detail = await scell.subTenants.get(tenant.id);
// Find by external ID
const found = await scell.subTenants.findByExternalId('partner-001');
// Update a sub-tenant
await scell.subTenants.update(tenant.id, { name: 'Partner Corp (Updated)' });
// Get sub-tenant stats
const stats = await scell.subTenants.statsOverview(tenant.id);
// Delete a sub-tenant
await scell.subTenants.delete(tenant.id);
// --- Supervision SuperPDP ---
// Path: /api/v1/tenant/sub-tenants/{id}/... (middleware tenant.key).
// Statut OAuth2 + KYB courant (cache 5 min)
const status = await scell.subTenants.getSuperPdpStatus(tenant.id);
// Forcer un poll cote SuperPDP (rate-limit 1/min)
// 422 MISSING_ACCESS_TOKEN -> e.authorize_url a ouvrir dans le navigateur
try {
await scell.subTenants.refreshSuperPdpStatus(tenant.id);
} catch (e) {
if (e.code === 'MISSING_ACCESS_TOKEN') {
window.open(e.authorize_url, '_blank', 'noopener');
}
}
// Generer une URL OAuth fresh (sans passer par refresh)
const { authorize_url, state } = await scell.subTenants.superpdpAuthorize(tenant.id);
// Regenerer une URL signee (7j) pour reprendre le tunnel onboarding
const { resume_url } = await scell.subTenants.getResumeUrl(tenant.id);
// --- Delete avec politique ISCA ---
try {
await scell.subTenants.delete(tenant.id);
} catch (e) {
if (e.code === 'SUB_TENANT_HAS_COMPANIES') {
// Demander confirmation a l'utilisateur, puis cascade
await scell.subTenants.delete(tenant.id, { cascade: true });
} else if (e.code === 'SUB_TENANT_HAS_FISCAL_ENTRIES') {
// Factures emises -> impossible de supprimer. Desactiver a la place.
await scell.subTenants.update(tenant.id, { is_active: false });
}
}

Échéancier de paiement

v2.13.0

Attachez un échéancier de paiement contractualisé à un devis. Lignes par % ou montant TTC, par date OU jalon textuel (« Livraison MVP », « Mise en prod »). Auto-génération de factures d'acompte à la date prévue. Tracker du solde restant à facturer. Échéancier verrouillé dès la signature (immutable post-acceptation). Accessible via $client->quotes->paymentSchedule (PHP) ou client.quotes.paymentSchedule (JS).

Méthodes: set, list/get, patch, delete, summary, convertLine, presets

Règles métier: somme des lignes ≤ total TTC ; chaque jalon indépendant ; immutable post-signature ; 1 conversion par ligne max.

payment-schedule.ts
typescript
// TypeScript — @scell/sdk v2.13.0
import { ScellClient } from '@scell/sdk';
const client = new ScellClient({ apiKey: 'sk_live_...' });
// Créer / remplacer l'échéancier
await client.quotes.paymentSchedule.set('quote-uuid', [
{ amount_type: 'percent', amount_value: 30,
milestone_label: 'À la commande',
auto_generate: true, due_date: '2026-06-01' },
{ amount_type: 'percent', amount_value: 70,
milestone_label: 'À la livraison' },
]);
// Tracker du solde restant
const summary = await client.quotes.paymentSchedule.summary('quote-uuid');
// → { schedule, invoiced: { gross_ttc, net_ttc, remaining_ttc, remaining_pct }, next_due, overdue, superpdp_status }
// Convertir une ligne en facture d'acompte
const invoice = await client.quotes.paymentSchedule.convertLine(
'quote-uuid', 'line-uuid',
{ send_email: true }
);
// 4 presets disponibles
const presets = await client.quotes.paymentSchedule.presets();

Envoi facture par email

v2.13.0

Envoyez une facture par email Scell.io générique avec PDF Factur-X en pièce jointe. Cascade de résolution du destinataire : override → buyer.billing_emailbuyer.emailquote.buyer_email. Si la facture est en draft, transition automatique vers validated + soumission SUPER PDP. Accessible via client.invoices.sendByEmail().

send-by-email.ts
typescript
// TypeScript
const result = await client.invoices.sendByEmail('invoice-uuid', {
recipient_email: 'compta@buyer.com', // optionnel
cc: ['manager@buyer.com'],
message: 'Merci pour votre confiance',
});
// → { sent_to, sent_at, message_id, cc }

Branding tenant / sub-tenant

v2.13.0

Personnalisez le branding de vos emails (logo, couleur primaire, footer, signature). Par défaut, Scell.io applique son branding générique. Si TOUS les champs (brand_logo_url, brand_primary_color, brand_email_footer) sont renseignés, vos emails utilisent votre branding. Disponible au niveau tenant master et sub-tenant. Upload de logo via URL pré-signée S3.

branding.ts
typescript
// TypeScript
// Tenant master
const branding = await client.branding.tenant.get();
// → { is_complete, missing_fields, brand_logo_url, brand_primary_color, ... }
await client.branding.tenant.update({
brand_logo_url: 'https://cdn.scell.io/.../logo.png',
brand_primary_color: '#1A73E8',
brand_email_footer: 'Société XYZ — SIRET 123456789',
});
// Sub-tenant
await client.branding.subTenants.update('sub-tenant-uuid', {
brand_primary_color: '#10B981',
});
// Upload logo (presigned S3)
const signed = await client.branding.tenant.uploadLogo('image/png');
// Then PUT the file to signed.url

Callback URL post-signature

v2.13.1

Fournissez une callback_url à la création du devis. Après acceptation ou refus via le viewer public, le buyer est redirigé vers cette URL avec query string : ?status=signed|refused&quote_id=<UUID>&quote_number=<num>&reason=<txt>. Permet d'intégrer la signature dans votre propre flow métier (page de remerciement, dashboard client, automation). Sans callback_url, le buyer voit la page de confirmation Scell.io par défaut.

Format: URL absolue HTTPS, max 500 caractères

Query string ajoutée: status (signed|refused), quote_id, quote_number, reason (si refus)

callback-url.ts
typescript
// TypeScript — @scell/sdk v2.13.1
import { ScellClient } from '@scell/sdk';
const client = new ScellClient({ apiKey: 'sk_live_...' });
await client.quotes.create({
issue_date: '2026-05-24',
valid_until: '2026-06-24',
buyer_id: 'buyer-uuid',
lines: [{ description: 'Mission', quantity: 1, unit_price_ht: 12000, tax_rate: 20 }],
total_ht: 12000, total_tax: 2400, total_ttc: 14400,
callback_url: 'https://mon-site.com/devis-signe',
});
// Buyer signe -> redirige vers :
// https://mon-site.com/devis-signe?status=signed&quote_id=...&quote_number=DEV-2026-0042
//
// Buyer refuse avec motif "Prix trop élevé" -> :
// https://mon-site.com/devis-signe?status=refused&quote_id=...&quote_number=...&reason=Prix+trop+%C3%A9lev%C3%A9

PaymentSummary enrichi + parité SDKs

v2.14.0

Le payload GET /api/v1/quotes/{id}/payment-summary expose désormais le champ lines: PaymentScheduleLine[] en plus des agrégats (schedule, invoiced, next_due, overdue, superpdp_status). Permet d'afficher le tracker visuel complet — highlight de la prochaine échéance, grisé des passées, rouge des overdue — sans seconde requête. Côté MCP, 11 nouveaux tools sont documentés pour atteindre la parité totale avec le backend.

Nouveaux tools MCP: regenerate_quote_public_link, revoke_quote_public_link, get_quote_pdf, preview_quote_pdf, get/set/patch/delete_quote_payment_schedule, get_quote_payment_summary, convert_schedule_line_to_invoice, list_payment_schedule_presets

summary-lines.ts
typescript
// TypeScript — @scell/sdk v2.14.0
const summary = await client.quotes.paymentSchedule.summary('quote-uuid');
// summary.lines est maintenant peuplé : PaymentScheduleLine[]
summary.lines.forEach((line) => {
const isNext = line.id === summary.next_due?.line_id;
const isOverdue = line.is_overdue;
const isPast = line.status === 'invoiced';
// → render tracker visuel avec highlight
});
// summary.invoiced.remaining_ttc = montant restant à facturer
// summary.invoiced.remaining_pct = % restant

Acomptes standalone (sans devis)

v2.15.0

Créez des factures d'acompte directement via POST /invoices sans passer par un devis. Indiquez le montant total du deal (deposit_total_ht) et une référence libre (deposit_reference_text). Liez les acomptes suivants via deposit_group_id. Quand la somme atteint 100%, le dernier acompte est automatiquement converti en facture de solde (type 380 + déductions BG-22 Factur-X).

standalone-deposit.ts
typescript
import { ScellApiClient } from '@scell/sdk';
const scell = new ScellApiClient('sk_live_your_api_key');
// ── 1. First deposit: create a new group ────────────────────────
const deposit1 = await scell.invoices.create({
invoice_type: 'deposit',
deposit_total_ht: 10000, // Total deal = 10 000 € HT
deposit_reference_text: 'Proposition commerciale signée le 15/05/2026',
direction: 'outgoing',
output_format: 'facturx',
issue_date: '2026-05-15',
due_date: '2026-05-30',
total_ht: 3000, // 30% deposit
total_tax: 600,
total_ttc: 3600,
seller_siret: '12345678901234',
seller_name: 'Ma Société',
seller_address: { line1: '1 rue Example', postal_code: '75001', city: 'Paris', country: 'FR' },
buyer_name: 'Client SA',
buyer_siret: '98765432109876',
buyer_address: { line1: '2 avenue Test', postal_code: '69001', city: 'Lyon', country: 'FR' },
lines: [{ description: 'Acompte 30%', quantity: 1, unit_price: 3000, tax_rate: 20, total_ht: 3000, total_tax: 600, total_ttc: 3600 }],
});
// deposit1.deposit_group_id = deposit1.id (self-reference)
// ── 2. Second deposit: join the group ───────────────────────────
const deposit2 = await scell.invoices.create({
invoice_type: 'deposit',
deposit_group_id: deposit1.deposit_group_id, // Link to group
// deposit_total_ht and deposit_reference_text inherited from group leader
direction: 'outgoing',
output_format: 'facturx',
issue_date: '2026-06-15',
total_ht: 7000, // Remaining 70% → auto-converted to balance
total_tax: 1400,
total_ttc: 8400,
seller_siret: '12345678901234',
seller_name: 'Ma Société',
seller_address: { line1: '1 rue Example', postal_code: '75001', city: 'Paris', country: 'FR' },
buyer_name: 'Client SA',
buyer_siret: '98765432109876',
buyer_address: { line1: '2 avenue Test', postal_code: '69001', city: 'Lyon', country: 'FR' },
lines: [{ description: 'Solde 70%', quantity: 1, unit_price: 7000, tax_rate: 20, total_ht: 7000, total_tax: 1400, total_ttc: 8400 }],
});
// deposit2.invoice_type === 'balance' (auto-converted: sum = 100%)
// deposit2.parent_invoice_ids === [deposit1.id] (BG-22 deductions)
// ── 3. Check group progress ─────────────────────────────────────
const invoice = await scell.invoices.get(deposit1.id);
console.log(invoice.deposit_group_progress);
// { deposit_total_ht: 10000, sum_deposits_ht: 3000, remaining_ht: 7000,
// progress_percent: 30, has_balance: true, invoices_count: 2 }

MCP Agent@scell/mcp-client v2.14.0

Utilisez Scell.io directement depuis votre assistant IA. L'agent MCP expose plus de 40 outils permettant à Claude, Cursor ou VS Code Copilot de créer des factures, gérer des signatures, planifier des échéanciers et surveiller la conformité fiscale en langage naturel.

Configuration

~/.claude/.mcp.json
json
// Coller ce bloc dans le fichier de config MCP de votre client IA.
// Cree le fichier s'il n'existe pas (chemin selon le client) :
//
//   - Claude Code (CLI)   ~/.claude/.mcp.json
//   - Claude Desktop      ~/Library/Application Support/Claude/claude_desktop_config.json   (macOS)
//                         %APPDATA%\\Claude\\claude_desktop_config.json                  (Windows)
//   - Cursor              ~/.cursor/mcp.json
//   - VS Code (Copilot)   ~/.vscode/mcp.json
//
// Remplacer sk_live_xxxx par votre cle Scell.io (sk_live_* en prod, sk_test_* en sandbox).
// Recuperez vos cles depuis le dashboard : https://app.scell.io/dashboard/api-keys

{
  "mcpServers": {
    "scell": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://api.scell.io/api/mcp",
        "--header",
        "X-Scell-API-Key: sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
      ]
    }
  }
}

Invoices6 outils

OutilDescriptionExemple de prompt
create_invoiceCreate a Factur-X/UBL/CII electronic invoice (optional `parentQuoteId` to link a standard invoice to a source quote, since v2.20.0)"Create a Factur-X invoice from ACME Corp to Client SA for 10 hours of consulting at 150 EUR/h, linked to quote DEV-2026-0042"
list_invoicesList all invoices with optional filters"Show me all invoices from this month"
get_invoiceGet details of a specific invoice by ID"Get details for invoice inv_abc123"
submit_invoiceSubmit an invoice to the PDP network"Submit invoice inv_abc123 to the PDP"
download_invoiceDownload an invoice as PDF or XML"Download the PDF for invoice inv_abc123"
mark_invoice_paidMark an outgoing invoice as paid (manual)"Mark invoice inv_abc123 as paid"

Signatures4 outils

OutilDescriptionExemple de prompt
create_signatureCreate an eIDAS EU-SES signature request"Create a signature request for agreement.pdf with 2 signers: Jean Dupont and Marie Martin"
list_signaturesList all signature requests"List all pending signature requests"
get_signatureGet signature request details"What's the status of signature sig_xyz789?"
cancel_signatureCancel a pending signature request"Cancel signature request sig_xyz789"

Credit Notes2 outils

OutilDescriptionExemple de prompt
create_credit_noteCreate a credit note linked to an invoice"Create a credit note for invoice inv_abc123 with a 150 EUR refund"
list_credit_notesList all credit notes"Show all credit notes issued this quarter"

Companies3 outils

OutilDescriptionExemple de prompt
get_companyGet company details"Show me the details for company comp_id"
list_companiesList all registered companies"List all my companies"
create_companyRegister a new company"Register company ACME Corp with SIREN 123456789"

Billing5 outils

OutilDescriptionExemple de prompt
get_balanceGet current tenant credit balance"What's my current credit balance?"
list_billing_transactionsList billing transactions (debits + credits)"Show my last 10 billing transactions"
list_billing_invoicesList Scell.io billing invoices issued to your account"List my Scell.io billing invoices for this year"
get_billing_usageGet current period usage metrics with projection"How many invoices did I send this month?"
scell_pay_billing_invoiceInitiate Stripe payment for a Scell.io billing invoice (returns client_secret)"Pay my latest Scell.io billing invoice"

Webhooks2 outils

OutilDescriptionExemple de prompt
list_webhooksList all webhook endpoints"Show all my webhook endpoints"
create_webhookCreate a new webhook endpoint"Create a webhook at https://myapp.com/hook for invoice.created events"

Fiscal12 outils

OutilDescriptionExemple de prompt
get_fiscal_complianceGet fiscal compliance status"Am I ISCA compliant?"
get_fiscal_entriesGet immutable ledger entries"Show the last 50 fiscal entries"
get_fiscal_closingsList daily/monthly closings"Show all fiscal closings for March 2026"
fiscal_daily_closingTrigger a daily fiscal closing"Run the daily fiscal closing now"
get_fiscal_integrityVerify hash chain integrity"Verify fiscal data integrity"
get_fec_exportExport FEC file for tax authorities"Generate the FEC export for 2025"
get_attestationGet ISCA attestation for a year"Get my ISCA attestation for 2025"
get_kill_switch_statusGet kill switch status"Is the kill switch active?"
activate_kill_switchActivate emergency kill switch"Activate the kill switch immediately"
deactivate_kill_switchDeactivate kill switch"Deactivate the kill switch"
get_fiscal_rulesList fiscal automation rules"Show all fiscal rules"
create_fiscal_ruleCreate a fiscal automation rule"Create a rule to auto-close daily at midnight"

Sub-Tenants2 outils

OutilDescriptionExemple de prompt
list_sub_tenantsList all sub-tenants"Show all my sub-tenants"
create_sub_tenantCreate a new sub-tenant"Create a sub-tenant for Partner Corp with external ID partner-001"

Événements webhook

Liste complète des événements webhook auxquels vous pouvez vous abonner. Utilisez ces noms d'événements lors de la création ou la mise à jour des endpoints webhook.

ÉvénementDescription
invoice.createdFacture créée
invoice.validatedFacture validée (Factur-X/UBL généré)
invoice.transmittedFacture transmise au PDP
invoice.acceptedFacture acceptée par le destinataire
invoice.rejectedFacture rejetée
invoice.errorErreur de traitement de la facture
invoice.refund_status_changedStatut de remboursement modifié (avoir)
signature.createdDemande de signature créée
signature.signedDocument signé par un signataire
signature.completedTous les signataires ont signé
signature.refusedSignature refusée par un signataire
signature.expiredDemande de signature expirée
balance.lowSolde de crédits faible (seuil d'alerte)
balance.criticalSolde de crédits critique

Statuts de facture

Liste complète des statuts possibles sur le champ status du payload Invoice (check constraint PostgreSQL côté backend). Les statuts marqués Auto sont posés automatiquement par le système (workers, observers, webhooks) — vous n'avez pas à les écrire. Les statuts refunded et partially_refunded sont posés par le CreditNoteObserver dès qu'un avoir validé est attaché à une facture — à utiliser côté lecture uniquement.

StatutAutoDescription
draftBrouillon. Modifiable et supprimable. Pas encore validé.
validatingOuiValidation Factur-X/UBL en cours (génération PDF/A-3).
validatedValidé. Hash fiscal posé, ledger ISCA immutable. Soumission PDP possible.
convertingOuiConversion de format en cours (Factur-X ↔ UBL ↔ CII).
convertedOuiFormat cible généré, prêt pour transmission.
transmittingOuiTransmission au PDP/PPF en cours.
transmittedOuiTransmise au réseau, en attente de réponse du destinataire.
acceptedOuiAcceptée par le destinataire via le PDP.
rejectedOuiRejetée par le destinataire ou le PDP.
disputedContestée par le destinataire. Action humaine requise.
paidPayée. Posé par mark-paid ou webhook bancaire.
receivedOuiFacture entrante reçue via le PDP (direction incoming).
completedOuiCycle terminé (paiement confirmé + post-traitement).
errorOuiErreur technique non récupérable. Voir metadata.last_error.
refundedOuiTotalement avoirée. Posé automatiquement par le backend quand la somme des avoirs validés ≥ total TTC.
partially_refundedOuiPartiellement avoirée. Posé automatiquement quand un avoir validé est attaché sans atteindre le total TTC.

Champs liés au remboursement

Deux champs accompagnent les statuts refunded et partially_refunded sur tout payload Invoice retourné par GET /invoices/{id} ou GET /invoices.

  • refund_status'none' | 'partial' | 'full'. Granularité fine de l'état de remboursement, indépendamment du statut principal (une facture paid puis partially_refunded reste en refund_status='partial').
  • total_refundedFloat, montant TTC cumulé remboursé via les avoirs validés. Source de vérité pour le reporting (la somme se reflète sur refund_status automatiquement).
Exemple — Payload Invoice (extrait)
json
{
  "id": "inv_01HXP3K7M2YQ9V8B5N6Z4A1C2D",
  "invoice_number": "QRCOM-202605-00001",
  "status": "partially_refunded",
  "refund_status": "partial",
  "total_refunded": 250.00,
  "total_amount": 1200.00,
  "currency": "EUR",
  "invoice_type": "standard",
  "buyer": { /* ... */ },
  "lines": [ /* ... */ ],
  "metadata": { /* ... */ }
}

Énumérations & statuts

Liste exhaustive des 19 énumérations exposées par l'API au-delà de InvoiceStatus. Les 8 premières sont des BackedEnum PHP synchronisées vers TypeScript via la commande php artisan types:generate (codegen back→front). Les 11 suivantes sont des contraintes CHECK PostgreSQL exposées par les payloads JSON de l'API.

Les SDK TypeScript (@scell/sdk), PHP (scell/sdk) et MCP (@scell/mcp-client) typent strictement ces valeurs côté client. Le ledger ISCA s'appuie sur les valeurs string telles quelles, sans alias.

ÉnumérationValeursDescription
InvoiceTemplateKind
App\Enums\Invoice\InvoiceTemplateKind
invoicequoteboth
Détermine si un template Factur-X est utilisable pour les factures, les devis, ou les deux.
InvoiceType
App\Enums\Invoice\InvoiceType
standarddepositbalance
Type de facture. `deposit` = acompte (TVA exigible immédiatement, CGI 289). `balance` = solde (déduit les acomptes via BG-22 code 80).
PaymentScheduleLineAmountType
App\Enums\Quote\PaymentScheduleLineAmountType
percentamount
Mode d'une ligne d'échéancier de devis : pourcentage du total TTC ou montant fixe en devise.
PaymentScheduleLineStatus
App\Enums\Quote\PaymentScheduleLineStatus
pendinginvoicedcancelled
État d'une ligne d'échéancier de devis. `invoiced` est posé automatiquement lors de la génération de la facture acompte/solde correspondante.
QuoteStatus
App\Enums\Quote\QuoteStatus
draftsentviewedacceptedrefusedexpiredconvertedcancelled
Cycle de vie d'un devis. `viewed` et `accepted/refused` sont posés via l'URL publique signée. `converted` quand un solde a été émis.
QuoteAuditAction
App\Enums\Quote\QuoteAuditAction
createdupdatedline_addedline_removedline_updatedbuyer_changedsentresentviewedsignedacceptedrefusedcancelledexpiredconvertedpublic_link_regeneratedpublic_link_revokedduplicateddeposit_generated_from_scheduleschedule_updatedschedule_deleted
21 actions journalisées dans `quote_audit_logs` (chaîne SHA-256 indépendante du ledger fiscal ISCA).
SubTenantOnboardingStatus
App\Enums\SubTenantOnboardingStatus
pending_superpdpsuperpdp_redirectedsuperpdp_authorizedsuperpdp_pending_reviewactivesuperpdp_failed
Cycle de vie de l'onboarding SuperPDP d'un sub-tenant via le widget `<scell-onboarding>`. `active` = KYB vérifié, B2B en mode Peppol.
VatCategory
App\Enums\Billing\VatCategory
STANDARDINTERMEDIATEREDUCEDSUPER_REDUCEDZERO_RATEDEXEMPTREVERSE_CHARGEOUT_OF_SCOPE
Catégorie de TVA EN16931. `REVERSE_CHARGE` = autoliquidation (intracom B2B). `OUT_OF_SCOPE` = hors champ (CGI 259 A, services hors-UE).
CreditNoteStatus
DB check constraint
draftsent
État d'un avoir. `draft` = modifiable/supprimable. `sent` = irréversible (entrée fiscale ISCA posée).
CreditNoteType
DB check constraint
partialtotal
Type d'avoir. `total` = avoir intégral, met la facture en `refunded`. `partial` = avoir partiel, déclenche `partially_refunded`.
SignatureStatus
DB check constraint
pendingwaiting_signerspartially_signedcompletedrefusedexpirederror
Cycle de vie d'une demande de signature eIDAS EU-SES. `completed` = tous les signataires ont signé, fichier de preuve disponible.
SignatureArchiveStatus
DB check constraint
pendingarchivedglaciererror
État d'archivage long terme d'une signature (10 ans). `glacier` = stockage froid S3 Glacier.
InvoiceArchiveStatus
DB check constraint
pendingarchivedglaciererror
État d'archivage long terme d'une facture (Object Lock COMPLIANCE 11 ans, conformité ISCA).
TenantKybStatus
DB check constraint
pendingdocuments_submittedunder_reviewverifiedrejected
Statut KYB du tenant master. `verified` est requis en production pour émettre des factures B2B.
CompanyStatus
DB check constraint
pending_kycactivesuspended
État d'une Company. `active` est requis pour qu'une Company soit émettrice de factures.
ApiKeyStatus
DB check constraint
activerevoked
État d'une clé API. `revoked` est irréversible (audit trail conservé).
TenantInvoiceStatus
DB check constraint
draftsentpaidoverduecancelled
État d'une facture de facturation Scell.io émise au tenant (consommation, packs, top-up). `overdue` est posé par le cron J+30.
TenantTransactionType
DB check constraint
debitcredit
Type d'une transaction de facturation tenant. `debit` = consommation. `credit` = top-up ou pack.
OnboardingSessionStatus
DB check constraint
initiatedsiret_verifiedvat_verifieddocuments_pendingdocuments_submittedunder_reviewcompletedfailedexpired
État d'une session d'onboarding sub-tenant via le widget public (cycle de vie complet du tunnel KYB).

Synchronisation des SDK

Les nouvelles versions v2.21.0 (PHP), v2.23.0 (TypeScript) et v2.22.0 (MCP) exposent ces 19 énumérations de façon typée. Côté PHP elles vivent dans Scell\\Sdk\\Enums\\* ; côté TypeScript dans des union types exportés ; côté MCP dans les descriptions d'outils consommées par le LLM.

Gestion des erreurs

Toutes les méthodes SDK lèvent des exceptions typées avec des codes de statut HTTP. Gérez les erreurs en fonction du code de statut.

CodeStatutDescription
400Bad RequestCorps de requête malformé ou paramètres invalides
401UnauthorizedIdentifiants d'authentification manquants, invalides ou expirés
402Payment RequiredSolde de crédits insuffisant pour effectuer l'opération
403ForbiddenIdentifiants valides mais permissions insuffisantes sur la ressource
404Not FoundLa ressource demandée n'existe pas
409ConflictRessource déjà existante ou conflit d'état (ex. soumission en doublon)
422Unprocessable EntityErreur de validation. Consultez l'objet errors pour les détails par champ
429Too Many RequestsLimite de taux dépassée. Vérifiez l'en-tête Retry-After
500Server ErrorErreur serveur interne. Réessayez avec un backoff exponentiel
503Service UnavailableService temporairement indisponible. Réessayez après un court délai

Stratégie de relance

  • 1.429 Rate LimitedRespectez l'en-tête Retry-After. Le SDK relance automatiquement jusqu'à 3 fois avec le délai indiqué.
  • 2.500/503 Server ErrorRelancez avec un backoff exponentiel : 1s, 2s, 4s. Max 3 relances. Le SDK gère cela automatiquement.
  • 3.4xx Client ErrorNe relancez pas. Corrigez le payload de la requête ou les identifiants et réessayez.
error-handling.ts
typescript
import { ScellApiClient } from '@scell/sdk';
const scell = new ScellApiClient('sk_live_your_api_key');
try {
const invoice = await scell.invoices.create({ /* ... */ });
} catch (error) {
if (error.status === 422) {
// Validation error — check error.errors for field-level details
console.error('Validation:', error.errors);
// { "seller.siren": ["The siren must be 9 digits."] }
} else if (error.status === 401) {
// Invalid or expired API key
console.error('Authentication failed');
} else if (error.status === 402) {
// Insufficient credits
console.error('Insufficient balance — top up credits');
} else if (error.status === 404) {
// Resource not found
console.error('Resource not found');
} else if (error.status === 429) {
// Rate limited — retry after error.retryAfter seconds
console.error('Rate limited, retry after', error.retryAfter, 'seconds');
} else if (error.status >= 500) {
// Server error — retry with exponential backoff
console.error('Server error, retrying...');
}
}

Prêt à intégrer ?

Créez votre compte et obtenez vos clés API en quelques minutes. Commencez avec 100 crédits offerts.

Vos préférences cookies

Nous utilisons des cookies pour améliorer votre expérience. Les cookies essentiels sont toujours actifs. Politique cookies.