Développeurs

Un ERP sur lequel on peut bâtir

Tout ce que fait le produit passe par la même surface ouverte : une API REST par jeton, des modèles découvrables par organisation, des webhooks signés HMAC et une zone de test qui s'efface d'elle-même.

Démarrer en trois étapes

Aucun SDK requis — une clé, une URL de base et la référence interactive suffisent au premier appel.

1

Frapper une clé

Console → Clés d'API. Choisissez Test pour une clé sk_test_ liée à un jumeau bac à sable de votre organisation — ou Réel pour la production.

2

S'authentifier

Envoyez la clé en en-tête Bearer : Authorization: Bearer sk_… Les portées peuvent borner une clé aux entités et verbes exacts dont elle a besoin.

3

Ouvrir la référence

Le Swagger documente chaque route, filtre et lookup — découverte et webhooks compris — depuis le schéma vivant.

URL de base : https://updo.pro/api/public/v1 · Référence interactive de l'API

Un SDK Python, et une ligne de commande

`updo-sdk` enveloppe l’API publique : même jeton, même contrat, en objets Python. Il lit `UPDO_API_TOKEN` dans l’environnement — une clé `sk_test_` le pointe donc sur votre zone de test, une clé `sk_` sur vos données réelles, sans changer une ligne de code.

pip install updo-sdk
pip install "updo-sdk[cli]"   # + the updo command

Synchrone

from updo import UpdoClient

# Or: export UPDO_API_TOKEN=sk_test_...  (UPDO_BASE_URL to point elsewhere)
with UpdoClient(token="sk_test_...") as client:
    print(client.me().tenant_slug)

    products = client.entity("product")
    for p in products.iterate(where={"status": "active"}):
        print(p["sku"])

Asynchrone

from updo import AsyncUpdoClient

async with AsyncUpdoClient(token="sk_test_...") as client:
    products = await client.entity("product")
    async for p in products.iterate(where={"status": "active"}):
        print(p["sku"])

Ce que le client lève

AuthenticationError

Jeton absent, révoqué ou expiré (401).

PermissionDenied

Le jeton est valide mais la décision d’accès dit non, ou sa portée ne couvre pas le geste (403).

ValidationError

Le serveur a refusé la valeur — champ requis, choix non déclaré, règle métier (400).

NotFoundError

L’enregistrement n’existe pas, ou pas dans cette organisation (404).

ApprovalRequired

Ce n’est PAS une erreur : la transition est parkée en attente d’approbation (202). L’identifiant de la demande est porté par l’exception.

En ligne de commande

Installé avec l’extra `[cli]`. Utile pour explorer une entité, sortir un export, ou générer des modèles typés depuis le modèle de données de VOTRE organisation.

updo get product --where status=active --limit 20
updo export product --format xlsx --out products.xlsx
updo codegen --out models.py

Paquet, versions et référence complète : pypi.org/project/updo-sdk

Découvrir le modèle

Les entités sont définies par organisation, alors l'API vous dit ce qui existe : GET /data/ liste chaque entité que votre clé peut lire, avec son URL de schéma. Une entité refusée est simplement absente — l'index n'est jamais un oracle.

Lire et écrire les enregistrements

Enveloppes génériques, filtres data__<champ> avec lookups, recherche libre, agrégat et pivot pour la BI, export CSV/XLSX — le tout borné par les mêmes décisions d'accès que le produit lui-même.

curl https://updo.pro/api/public/v1/data/ \
  -H "Authorization: Bearer sk_test_..."

Des webhooks gérés par l'API

Abonnez-vous à n'importe quel événement métier — invoice.paid, ticket.created, vos propres événements émis — directement par l'API. Chaque livraison est journalisée par tentative : code HTTP, durée et prochain essai, lisibles avec la même clé.

curl -X POST https://updo.pro/api/public/v1/webhooks/ \
  -H "Authorization: Bearer sk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "slug": "invoice-paid",
    "event_pattern": "invoice.paid",
    "config": {
      "url": "https://example.com/hooks/updo",
      "secret": "whsec_..."
    }
  }'

Le contrat de signature

X-Qlaris-Signature

sha256=<hex> — HMAC-SHA256 des octets exacts du corps de la requête, clé = le secret de votre abonnement.

X-Qlaris-Event

Le nom de l'événement qui a déclenché la livraison.

X-Qlaris-Delivery

Stable à travers les réessais d'un même événement — dédupliquez dessus.

X-Qlaris-Timestamp

Secondes Unix à l'envoi. Refusez tout ce qui a plus de 5 minutes pour bloquer les rejeux.

import hashlib, hmac

def verify(secret: str, raw_body: bytes, signature: str) -> bool:
    digest = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(f"sha256={digest}", signature)

Une zone de test qui fait son propre ménage

Une clé sk_test_ ouvre un jumeau bac à sable de votre organisation : mêmes modules, même modèle, données semées — et une frontière dure avec la production.

Un vrai jumeau

Le bac est provisionné par le même installeur que la production — ce qui marche là marche en vrai.

Inoffensif par construction

Les documents sortent avec un filigrane NOT TO USE et aucun courriel ne part réellement du bac.

Moindre privilège

Bornez une clé à data:<entité>:read, analytics:*, webhooks:write… Des portées vides = tous les droits des rôles de la clé.

Évaluez la plateforme sur votre activité

Créez votre espace en quelques minutes, avec les applications de votre profession déjà en place. Sans carte bancaire.