Aller au contenu principal

Rechercher des données

Ce guide explique comment récupérer le bon type de données selon votre usage, en utilisant l'API de recherche de Stonal avec des filtres, de la pagination et des schémas de recherche avancés.

info

Vous devrez obtenir un jeton d'accès personnel pour utiliser l'API de recherche.

Démarrage​

Authentification​

Voici un exemple de requête autour de l'API de recherche, où nous allons récupérer des BUILDING_GROUP et des BUILDING.

Vous devez passer une requête ressemblant à ceci :

📄 search.sh
#!/bin/sh -ex

# Your organization
STONAL_ORG=DEMO

# Fetch your token from here: https://app.stonal.io/users/app
STONAL_TOKEN=9631e269-e21e-4ce6-92a9-c6f7ed1fa98a

curl \
https://api.stonal.io/datalake/v1/organizations/$STONAL_ORG/assets/search \
-v \
-X POST \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $STONAL_TOKEN" \
-d @query.json -o output.json

Requête initiale​

📄 query.json
{
"search": {
"type": {
"equals": [
"BUILDING",
"BUILDING_GROUP"
]
}
},
"properties": {
"simple": ["LAT", "LNG"]
},
"fields": [
"name",
"type",
"uid",
"externalIds"
],
"paginate": {
"size": 2
}
}

La sortie sera semblable à ceci :

📄 output.json
{
"assets": [
{
"uid": "f6472f1a-9473-4fbf-9e1c-1c063eebb430",
"name": "Building Group 1",
"type": "BUILDING_GROUP",
"externalIds": {
"SOURCE_NAME": "BG001"
},
"properties": {
"simple": {
"LAT": "46.800",
"LNG": "1.6959"
}
}
},
{
"uid": "b81ce341-86f0-4cfe-a806-1d4a0f9a12ed",
"name": "Building 1",
"type": "BUILDING",
"externalIds": {
"SOURCE_NAME": "B001"
},
"properties": {
"simple": {
"LAT": "46.500",
"LNG": "1.7959"
}
}
}
],
"paginate": {
"size": 2,
"cursor": "123456"
}
}

Requêtes suivantes​

Ensuite, pour récupérer le lot suivant de 10 objets, vous devez émettre la même requête avec le paginate.cursor défini à la valeur reçue, c.-à-d. "123456".

📄 query.json
{
"search": {
"type": {
"equals": [
"BUILDING",
"BUILDING_GROUP"
]
}
},
"fields": [
"name",
"type",
"uid",
"externalIds",
"parent"
],
"paginate": {
"size": 2,
"cursor": "123456"
}
}

La sortie sera semblable à ceci :

📄 output.json
{
"assets": [
{
"uid": "dd127caf-5b9b-4116-884e-b42505ac1bd6",
"name": "Building Group 2",
"type": "BUILDING_GROUP",
"externalIds": {
"CODE": "BG002"
}
},
{
"uid": "2c2ca7be-78f1-4734-a4c6-bbc773c9027b",
"name": "Building 2",
"type": "BUILDING",
"externalIds": {
"CODE": "B002"
},
"parent": {
"uid": "dd127caf-5b9b-4116-884e-b42505ac1bd6"
}
}
],
"paginate": {
"size": 2,
"cursor": "234567"
}
}

Pour aller plus loin​

Il existe de nombreuses autres façons d'interroger les données. Et vous pouvez combiner n'importe lequel de ces filtres.

Rechercher par identifiants externes​

Vous pouvez effectuer une recherche à l'aide d'un seul identifiant externe, soit issu de l'objet lui-même, soit de ses relations.

Rechercher un objet précis par l'un de ses identifiants externes.

🔎 by asset's external ID
"search": {
"asset": {
"externalIds": {
"SOURCE_NAME": "BG001"
}
}
}

Rechercher les objets dont le parent correspond à l'identifiant externe donné.

🔎 by the external ID of asset’s parent
"search": {
"parent": {
"externalIds": {
"SOURCE_NAME": "BG001"
}
}
}

Recherche libre​

Utilisez q pour trouver les objets dont le nom ou l'identifiant externe contient un terme — typiquement pour alimenter une barre de recherche.

Le terme est cherché dans les deux champs à la fois et peut se trouver n'importe où dans la valeur, pas seulement au début. La casse et les accents sont ignorés.

🔎 assets whose name or external id contains '01S'
{
"search": { "q": "01S" },
"fields": ["uid", "name", "type", "externalIds"],
"paginate": { "size": 50 }
}

Il se combine aux autres filtres (avec un AND), ce qui permet de le restreindre à un type ou à une branche de la hiérarchie. Seule exception, includeDeleted et isDeleted : la recherche libre ne couvre que les objets non supprimés, et la combinaison renvoie une erreur de validation.

🔎 '01S' among the equipments of a site
{
"search": {
"q": "01S",
"type": { "matches": ["EQUIPMENT\\|.*"] },
"parentRecursive": { "externalIds": { "CODE": "SITE_001" } }
},
"fields": ["uid", "name", "type"],
"paginate": { "size": 50 }
}
remarque

Un terme de moins de 3 caractères, ou de plus de 500, est rejeté par une erreur de validation. Il est recherché comme une seule sous-chaîne, sans être découpé en mots : q: "Building 1" recherche la séquence building 1, et non building et 1 séparément. Seules les valeurs des identifiants sont parcourues, jamais le nom de leur source ; si vous connaissez déjà l'identifiant exact, asset.externalIds est le filtre approprié.

Les objets sont organisés selon une hiérarchie (voir Hiérarchie des objets). Vous pouvez utiliser les filtres de relation suivants pour naviguer vers le haut et vers le bas de l'arborescence. Un seul filtre de relation peut être utilisé par requête.

Trouver les enfants directs d'un parent​

Utilisez parent pour trouver tous les objets qui sont des enfants directs d'un objet parent donné.

🔎 direct children of a building group
"search": {
"parent": { "uid": "dd127caf-5b9b-4116-884e-b42505ac1bd6" }
}

Trouver tous les descendants d'un ancêtre​

Utilisez parentRecursive pour trouver tous les objets imbriqués sous un ancêtre donné, à n'importe quelle profondeur.

🔎 all descendants of a building group (buildings, plans, levels, spaces, equipments...)
"search": {
"parentRecursive": { "externalIds": { "CODE": "SITE_001" } }
}

Trouver les parents directs d'un enfant​

Utilisez child pour trouver les objets qui sont des parents directs d'un objet enfant donné.

🔎 direct parents of a building
"search": {
"child": { "uid": "b81ce341-86f0-4cfe-a806-1d4a0f9a12ed" }
}

Trouver tous les ancêtres d'un descendant​

Utilisez childRecursive pour trouver tous les objets ancêtres d'un descendant donné, à n'importe quelle profondeur. C'est utile pour remonter la hiérarchie depuis un objet feuille (par exemple un équipement) afin de trouver son bâtiment, sa résidence, etc.

🔎 find the building of an equipment
{
"search": {
"childRecursive": { "uid": "$equipmentUid" },
"type": { "equals": ["BUILDING", "BUILDING_SECTION"] }
},
"fields": ["name", "type"],
"paginate": { "size": 10 }
}

Vous pouvez aussi utiliser externalIds pour identifier le descendant :

🔎 find all ancestors of an equipment by external ID
"search": {
"childRecursive": {
"externalIds": { "TRIRIGA": "EQP1008473" }
}
}
remarque

childRecursive renvoie tous les ancêtres mais exclut des résultats l'objet enfant interrogé lui-même. Tous les autres filtres (type, name, fields, properties, paginate) s'appliquent normalement aux ancêtres renvoyés.

Trouver les objets regroupés par un parent de regroupement​

En plus de la hiérarchie, un objet peut être regroupé par d'autres objets : un PLAN|INDOOR est regroupé par son BUILDING logique, une ZONE par un RENTED_UNIT, une LEVEL_SECTION par une BUILDING_SECTION (voir Ingérer des données). Utilisez groupingParent pour lister les objets qu'un objet donné regroupe, et demandez le champ groupedBy pour lire les parents de regroupement de chaque résultat.

🔎 zones d'un lot, avec leurs parents de regroupement
{
"search": {
"groupingParent": { "externalIds": { "CODE": "RU_001" } }
},
"fields": ["name", "type", "groupedBy"]
}

Les filtres ci-dessus renvoient les objets liés sous forme de lignes. Pour obtenir, sur chaque résultat, le lot, le bâtiment ou le site auquel il appartient, utilisez plutôt la projection belongsTo à la racine de la requête (voir Récupérer ce à quoi chaque résultat appartient).

Correspondance sur un motif​

Vous pouvez rechercher des types correspondant à un motif d'expression régulière.

Rechercher des espaces​

remarque

SPACE est un autre nom pour les pièces dans la plateforme Stonal.

Ceci renverra des objets de types SPACE et SPACE|* :

🔎 asset type pattern
"search": {
"type": {
"matches": [
"SPACE",
"SPACE\\|.*"
]
}
}

Veuillez noter que ceci s'appliquera à tous les espaces de l'organisation. Si vous souhaitez le limiter à un bâtiment particulier, vous devriez le combiner avec un filtre parent comme ceci :

🔎 spaces within a specific building group
"search": {
"type": {
"matches": [
"SPACE",
"SPACE\\|.*"
]
},
"parent": {
"externalIds": {
"SOURCE_NAME": "BG001"
}
}
}

Exclure par type​

info

Un seul de notMatches ou notEquals est accepté (de même que matches et equals)

Par correspondance sur un motif​

Exclure des équipements spécifiés (ceux ayant un type commençant par EQUIPMENT|C|CA|) lors du listage des équipements d'une résidence

Using Regex to exclude types
"search": {
"type": {
"matches": ["EQUIPMENT\\|.*"],
"notMatches": ["EQUIPMENT\\|C\\|CA\\|.*"]
},
"parentRecursive": {
"externalIds": { "CODE": "SITE_001" }
}
}

Par égalité stricte​

Exclure des équipements spécifiés (ceux ayant un type égal à EQUIPMENT|C|CA|CA01 ou EQUIPMENT|A|AA) lors du listage des équipements d'une résidence

Using strict equality to exclude types
"search": {
"type": {
"matches": ["EQUIPMENT\\|.*"],
"notEquals": ["EQUIPMENT|C|CA|CA01", "EQUIPMENT|A|AA"]
},
"parentRecursive": {
"externalIds": { "CODE": "SITE_001" }
}
}

Filtrer sur la donnée courante d'une propriété​

Les objets portent des propriétés : des points de données comme l'adresse, la surface locative, la date de construction ou le nombre de locataires. Chaque propriété est identifiée par un code (par ex. ADDRESS, RENTAL_AREA, BUILDING_DATE, TENANT_COUNT).

info

Les codes de propriété pour chaque type d'objet sont listés dans le produit DQC. Voir Récupérer un sous-ensemble de propriétés pour plus de détails.

Ajoutez un bloc search.properties pour filtrer les objets selon les valeurs de leurs propriétés.

astuce

search.properties filtre quels objets sont renvoyés. Le properties de niveau racine contrôle quelles données apparaissent dans la réponse. Ils peuvent être utilisés ensemble.

Exemple : bâtiments du 8e arrondissement de Paris ayant plus de 2 locataires

{
"search": {
"properties": {
"conditions": [
{ "op": "gt", "property": "TENANT_COUNT", "value": "2" },
{ "op": "contains", "property": "ADDRESS", "value": "75008 Paris" }
]
},
"type": {
"equals": ["BUILDING"]
}
},
"fields": ["uid", "name", "type"],
"properties": {
"simple": ["TENANT_COUNT", "ADDRESS"]
},
"paginate": { "size": 50 }
}

Structure d'une condition​

Une condition est un objet comportant les champs suivants :

ChampDescription
opL'opérateur à appliquer (voir Opérateurs ci-dessous)
propertyLe code de propriété sur lequel filtrer (pour les conditions feuilles)
valueLa valeur à comparer (pour les opérateurs à valeur unique)
valuesUne liste de valeurs à comparer (pour les opérateurs in/notIn)
conditionsUne liste de conditions imbriquées (pour les opérateurs de groupe and/or)

Plusieurs conditions au niveau racine sont combinées avec un ET. Utilisez des groupes or/and pour une logique explicite :

🔎 address contains 75008 Paris OR more than 10 tenants
{ "op": "or", "conditions": [
{ "op": "contains", "property": "ADDRESS", "value": "75008 Paris" },
{ "op": "gt", "property": "TENANT_COUNT", "value": "10" }
]}

Les groupes peuvent être imbriqués :

🔎 main property type is Bureau AND (rental area > 500 OR more than 10 tenants)
{
"conditions": [
{ "op": "eq", "property": "MAIN_ASSET_NATURE", "value": "Bureau" },
{ "op": "or", "conditions": [
{ "op": "gt", "property": "RENTAL_AREA", "value": "500" },
{ "op": "gt", "property": "TENANT_COUNT", "value": "10" }
]}
]
}

Opérateurs​

Comparaison​

Les comparaisons de texte sont insensibles à la casse et aux accents (« chatelet » correspond à « Châtelet »).

OpérateurDescriptionChamps requis
eqÉgalvalue
neqDifférentvalue
inCorrespond à une valeur quelconque d'une listevalues (non vide)
notInNe correspond à aucune des valeursvalues (non vide)
🔎 main property type is Bureau
{ "op": "eq", "property": "MAIN_ASSET_NATURE", "value": "Bureau" }
🔎 main property type is Commerce or Logement
{ "op": "in", "property": "MAIN_ASSET_NATURE", "values": ["Commerce", "Logement"] }
Texte​
OpérateurDescriptionChamps requis
containsCorrespondance de sous-chaîne (insensible à la casse/aux accents)value
notContainsExclut la correspondance de sous-chaînevalue
regexCorrespondance par expression régulièrevalue (regex valide)
notRegexExclut la correspondance par regexvalue (regex valide)
🔎 address contains 'Rue du chat'
{ "op": "contains", "property": "ADDRESS", "value": "Rue du chat" }
Numérique et date​

Toutes les valeurs sont passées sous forme de chaînes mais doivent être un nombre valide (par ex. "100") ou une date ISO 8601 (par ex. "2024-01-15").

OpérateurDescriptionChamps requis
gtStrictement supérieur àvalue (nombre ou date)
gteSupérieur ou égal àvalue (nombre ou date)
ltStrictement inférieur àvalue (nombre ou date)
lteInférieur ou égal àvalue (nombre ou date)
🔎 rental area between 100 and 500
{
"conditions": [
{ "op": "gte", "property": "RENTAL_AREA", "value": "100" },
{ "op": "lte", "property": "RENTAL_AREA", "value": "500" }
]
}
🔎 buildings constructed after 2000
{ "op": "gt", "property": "BUILDING_DATE", "value": "2000-01-01" }
Présence​
OpérateurDescriptionChamps requis
isNullAucune valeur courante pour cette propriétéaucun (value/values doivent être absents)
isNotNullA une valeur couranteaucun (value/values doivent être absents)
🔎 assets with no address
{ "op": "isNull", "property": "ADDRESS" }
Groupes logiques​
OpérateurDescriptionChamps requis
andToutes les conditions imbriquées doivent correspondreconditions (au moins 2)
orAu moins une doit correspondreconditions (au moins 2)

Négation et données manquantes​

Les opérateurs de négation (neq, notIn, notContains, notRegex) excluent les objets qui n'ont aucune valeur pour la propriété. Pour les inclure, combinez avec isNull :

🔎 main property type is not Commerce or Parking, including assets without one
{ "op": "or", "conditions": [
{ "op": "notIn", "property": "MAIN_ASSET_NATURE", "values": ["Commerce", "Parking"] },
{ "op": "isNull", "property": "MAIN_ASSET_NATURE" }
]}

Récupérer un sous-ensemble de champs​

Les champs sont des attributs directement associés à un objet. Vous pouvez spécifier quels champs récupérer.

Valeurs autorisées : uid, name, updatedAt, deletedAt, type, externalIds, representations, parent, groupedBy, effectiveDate, expirationDate, integrationDate, childCount, containsChildCount, groupsChildCount

  • parent est le parent hiérarchique ; groupedBy est la liste des parents de regroupement (voir Naviguer dans la hiérarchie).
  • childCount compte tous les enfants, containsChildCount seulement les enfants hiérarchiques, groupsChildCount seulement les enfants regroupés.
  • Ce à quoi un objet appartient n'est pas un champ : demandez-le avec l'objet belongsTo à la racine de la requête (voir Récupérer ce à quoi chaque résultat appartient).

L'identifiant unique uid est toujours renvoyé.

🔎 get asset's name, date of update and external ids
{
"search": {
"asset": { "uid": "2cb3683a-90f6-48de-aaa0-08f45c7bf808" }
},
"fields": ["name", "updatedAt", "externalIds"]
}

Récupérer ce à quoi chaque résultat appartient​

childRecursive remonte depuis un seul objet par requête. Quand vous synchronisez tout un sous-arbre avec parentRecursive, cela signifierait un appel supplémentaire par objet pour savoir à quel lot, quel bâtiment ou quel site chaque équipement appartient. Demandez plutôt la projection belongsTo : ajoutez une liste belongsTo.types à la racine de la requête, et chaque objet renvoyé porte, pour chaque type demandé, les objets auxquels il appartient.

🔎 équipements d'un site, chacun avec son lot et son bâtiment
{
"search": {
"parentRecursive": { "externalIds": { "CODE": "SITE_001" } },
"type": { "matches": ["EQUIPMENT\\|.*"] }
},
"fields": ["name", "type", "parent"],
"belongsTo": { "types": ["RENTED_UNIT", "BUILDING"] },
"paginate": { "size": 50 }
}
➡️ réponse : une chaudière dans une zone regroupée par un lot, et une finition portée par le bâtiment lui-même
{
"assets": [
{
"uid": "7a0c6d3e-1f2b-4c5d-9e8f-0a1b2c3d4e5f",
"name": "Chaudière B-04",
"type": "EQUIPMENT|F|FA|FA01|FA0111",
"parent": { "uid": "4e1f9c2a-7b3d-4a6e-8c5f-2d1e0b9a8c7d" },
"belongsTo": {
"RENTED_UNIT": [ { "uid": "0d19bb25-78ee-413f-8291-1d122332064f" } ],
"BUILDING": [ { "uid": "b81ce341-86f0-4cfe-a806-1d4a0f9a12ed" } ]
}
},
{
"uid": "9c2e4b17-5d0a-4f8e-a3b6-71c8d2e9f0a4",
"name": "Peinture extérieure",
"type": "EQUIPMENT|C|CB|CB02|CB0211",
"parent": { "uid": "b81ce341-86f0-4cfe-a806-1d4a0f9a12ed" },
"belongsTo": {
"BUILDING": [ { "uid": "b81ce341-86f0-4cfe-a806-1d4a0f9a12ed" } ]
}
}
],
"paginate": { "size": 50, "cursor": "345678" }
}

Trois façons de parcourir la hiérarchie, faciles à confondre :

ancré sur un objet, renvoie des lignesappliqué à chaque objet renvoyé, renvoie un champ
descendparentRecursive—
remontechildRecursivebelongsTo

Comment belongsTo est résolu et comment le lire :

  • Vers le haut, à travers les relations de hiérarchie (parent) et de regroupement (groupedBy), à n'importe quelle profondeur. La chaudière ci-dessus atteint son lot bien que sa zone soit regroupée par le lot plutôt que contenue dedans.
  • La clé est le code que vous avez demandé : demander PLAN couvre aussi PLAN|INDOOR et PLAN|OUTDOOR, repliés sous la seule clé PLAN — vous n'avez jamais besoin de la nomenclature de types de l'organisation.
  • Seuls les codes effectivement trouvés sont des clés. Un code demandé sans correspondance, ou inconnu de votre organisation, est absent de l'objet — lisez-le comme belongsTo.<code> ?? []. Une clé absente est normale et fréquente, ce n'est pas un trou dans les données : un équipement de partie commune n'appartient à aucun lot, une finition de mur extérieur à aucune pièce — le second objet ci-dessus.
  • Chaque clé renvoie une liste sans ordre défini : un objet appartient en général à plusieurs niveaux à la fois, et le premier n'est pas le plus proche. En choisir un seul est une règle de priorité du système appelant.
  • Chaque entrée porte l'uid de l'objet, la même forme que parent et groupedBy ; pour obtenir leurs noms ou identifiants externes, interrogez-les dans un second appel avec le filtre assets. Les objets supprimés ne sont jamais renvoyés.
  • types accepte de 1 à 10 codes de type distincts (les doublons et les espaces autour sont ignorés). Il est indépendant de fields, et l'objet belongsTo n'est présent dans la réponse que s'il a été demandé.

Récupérer un sous-ensemble de propriétés​

Les propriétés sont associées à des données chronologiques liées à un objet.

Vous pouvez récupérer la donnée de référence d'une propriété spécifiée à l'instant courant.

info

Les éléments de la liste simple font référence au code de la propriété.

Ce code peut être trouvé dans notre produit DQC pour chaque type d'objet

Dans cet exemple, nous sommes sur un BUILDING, sa propriété nommée Adresse a ADDRESS pour code.

Capture d'écran depuis DQC sur une URL du type https://app.stonal.io/dqc/$ORGANIZATION_CODE/asset-types/EQUIPMENT/assets/$ASSET_UID dqc_building_properties.png

Nb : le code peut aussi avoir un format uuid

Dans cet exemple, nous sommes sur un EQUIPMENT, sa propriété nommée Date dernier renouvellement a 43f1f705-b3b3-4ff3-9ca3-a5c5ed638eef pour code.

Capture d'écran depuis DQC sur une URL du type https://app.stonal.io/dqc/$ORGANIZATION_CODE/asset-types/EQUIPMENT/assets/$ASSET_UID

dqc_equipment_properties.png

🔎 get building's data for ADDRESS and BUILDING_DATE property
{
"search": {
"type": { "equals": ["BUILDING"] }
},
"properties": {
"simple": ["ADDRESS", "BUILDING_DATE"]
}
}
➡️ response with current reference data for ADDRESS and BUILDING_DATE property
{
"assets": [
{
"uid": "1321987a-b94f-4180-ab93-94432be0855f",
"properties": {
"simple": {
"ADDRESS": "28 Cr Albert 1er, 75008 Paris",
"BUILDING_DATE": "2001-09-29"
}
}
}
]
}

Récupérer la source et l'historique d'une propriété​

Utilisez properties.precise au lieu de properties.simple quand vous avez besoin de la source de chaque valeur, de ses dates de validité, et de savoir si c'est la valeur de référence. Cas typique : synchroniser un modèle externe (BIM/Revit, votre propre base) et décider s'il faut écraser une valeur.

precise prend une liste codes et des filtres optionnels :

  • onlyReference (défaut true) : seulement la valeur de référence, ou false pour toutes les sources.
  • startDate / endDate (défaut : maintenant) : la fenêtre de validité. Omettez pour la valeur courante, mettez-les égales pour une date précise, ou élargissez pour l'historique.
🔎 get building's ADDRESS with its source
{
"search": { "type": { "equals": ["BUILDING"] } },
"properties": { "precise": { "codes": ["ADDRESS"] } }
}
➡️ response with the current reference value and its source
{
"assets": [
{
"uid": "1321987a-b94f-4180-ab93-94432be0855f",
"properties": {
"precise": {
"ADDRESS": [
{ "rawValue": "28 Cr Albert 1er, 75008 Paris", "source": "REVIT", "startDate": "2020-06-01", "isReference": true }
]
}
}
}
]
}

Comme properties.simple par défaut, precise renvoie la valeur de référence courante de chaque code, une entrée par code. source est le nom du système d'origine (par ex. REVIT, PIH, DATALAKE). Les bornes de date ouvertes sont omises. Une propriété sans valeur dans la fenêtre demandée n'est pas renvoyée.

Pour obtenir toutes les sources ou l'historique complet, mettez onlyReference: false et/ou une fenêtre plus large :

🔎 get every source of ADDRESS over 2010-2035
{
"search": { "type": { "equals": ["BUILDING"] } },
"properties": {
"precise": { "codes": ["ADDRESS"], "onlyReference": false, "startDate": "2010-01-01", "endDate": "2035-01-01" }
}
}

Mise à jour différentielle​

Vous pouvez rechercher les données qui ont été mises à jour depuis une date particulière.

🔎 differential update
"search": {
"updatedAtAfter": "2025-09-12T00:00:00"
}

Détecter les objets supprimés​

Dans la réponse de recherche, vous pouvez aussi inclure les objets supprimés correspondant aux filtres spécifiés.

🔎 detect deleted assets
"search": {
"updatedAtAfter": "2025-09-12T00:00:00",
"includeDeleted": true
}

Photos des objets​

Ceci s'applique principalement aux objets BUILDING_GROUP et BUILDING.

Si l'objet possède un PHOTO_ID, nous pouvons y accéder directement en utilisant ce modèle d'URL :

https://api.stonal.io/document-storage/v1/organizations/$org/documents/$photoId/content

Nous fournissons également un redimensionnement et une génération de miniatures pour les photos à l'aide d'imagor afin que vous puissiez l'utiliser directement dans votre API frontend :

https://cdn-api.stonal.io/imagor/unsafe/fit-in/200x/api.stonal.io/document-storage/v1/organizations/$org/documents/$photoId/content
info

Le unsafe dans l'URL signifie que vous n'avez pas besoin de signer l'URL, mais son usage est sûr.