{
  "info": {
    "name": "Bertel API v3.0",
    "description": "Collection Postman complète pour l'API Bertel v3.0 - OTI du Sud\n\nCette collection inclut tous les endpoints documentés avec leurs paramètres, exemples et variables d'environnement.\n\n## Authentification\nTous les endpoints nécessitent une authentification via headers (apikey, Authorization Bearer, etc.)\n\n## Variables d'environnement\n- `base_url`: URL de base de l'API\n- `apikey`: Votre clé API\n- `authorization`: Token Bearer (alternative)\n\n## Endpoints disponibles\n1. **get_object_resource** - Récupérer une ressource spécifique\n2. **list_object_resources_page** - Lister avec curseur (`p_cursor`) et taille de page (`p_page_size`)\n3. **list_object_resources_since_fast** - Lister depuis une date (keyset)\n4. **list_object_resources_filtered_page** - Lister avec filtres riches (curseur + `p_page_size`)\n5. **list_object_resources_filtered_since_fast** - Filtres + depuis une date (keyset)",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
    "_postman_id": "bertel-api-v3-collection"
  },
  "item": [
    {
      "name": "1. Authentication & Headers",
      "item": [
        {
          "name": "Test Authentication",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "apikey",
                "value": "{{apikey}}",
                "description": "Votre clé API"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_object_id\": \"test-id\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/get_object_resource",
              "host": ["{{base_url}}"],
              "path": ["rpc", "get_object_resource"]
            },
            "description": "Test simple pour vérifier l'authentification"
          }
        }
      ],
      "description": "Tests d'authentification et configuration des headers"
    },
    {
      "name": "2. Core Endpoints",
      "item": [
        {
          "name": "Get Object Resource",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "apikey",
                "value": "{{apikey}}"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_object_id\": \"{{object_id}}\",\n  \"p_lang_prefs\": [\"fr\", \"en\"],\n  \"p_track_format\": \"none\",\n  \"p_options\": {\n    \"include_stages\": false,\n    \"stage_color\": \"#FF0000\"\n  }\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/get_object_resource",
              "host": ["{{base_url}}"],
              "path": ["rpc", "get_object_resource"]
            },
            "description": "Récupérer toutes les données d'un objet spécifique. Inclut optionnellement le tracé KML/GPX pour les itinéraires."
          },
          "response": [
            {
              "name": "Success Response",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "apikey",
                    "value": "{{apikey}}"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"p_object_id\": \"example-id\"\n}"
                },
                "url": {
                  "raw": "{{base_url}}/rpc/get_object_resource",
                  "host": ["{{base_url}}"],
                  "path": ["rpc", "get_object_resource"]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n  \"object_id\": \"example-id\",\n  \"type\": \"ITI\",\n  \"status\": \"published\",\n  \"name\": {\n    \"fr\": \"Exemple d'itinéraire\",\n    \"en\": \"Example itinerary\"\n  },\n  \"description\": {\n    \"fr\": \"Description de l'itinéraire...\",\n    \"en\": \"Itinerary description...\"\n  },\n  \"geometry\": {\n    \"type\": \"LineString\",\n    \"coordinates\": [[4.85, 45.75], [4.86, 45.76]]\n  },\n  \"track_data\": null\n}"
            }
          ]
        },
        {
          "name": "List Object Resources (Page)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "apikey",
                "value": "{{apikey}}"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_cursor\": null,\n  \"p_page_size\": 20,\n  \"p_types\": [\"ITI\", \"HER\"],\n  \"p_status\": [\"published\"],\n  \"p_search\": \"rando\",\n  \"p_lang_prefs\": [\"fr\"],\n  \"p_track_format\": \"none\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/list_object_resources_page",
              "host": ["{{base_url}}"],
              "path": ["rpc", "list_object_resources_page"]
            },
            "description": "Lister les ressources avec pagination par curseur. Idéal pour la navigation classique et stable."
          },
          "response": [
            {
              "name": "Success Response",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "apikey",
                    "value": "{{apikey}}"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"p_cursor\": null,\n  \"p_page_size\": 20\n}"
                },
                "url": {
                  "raw": "{{base_url}}/rpc/list_object_resources_page",
                  "host": ["{{base_url}}"],
                  "path": ["rpc", "list_object_resources_page"]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n  \"info\": {\n    \"kind\": \"page\",\n    \"language\": \"fr\",\n    \"language_fallbacks\": [\"fr\"],\n    \"page\": 1,\n    \"limit\": 20,\n    \"total\": 150,\n    \"total_pages\": 8\n  },\n  \"data\": [\n    {\n      \"object_id\": \"iti-001\",\n      \"type\": \"ITI\",\n      \"status\": \"published\",\n      \"name\": {\n        \"fr\": \"Sentier des crêtes\"\n      }\n    }\n  ]\n}"
            }
          ]
        },
        {
          "name": "List Object Resources (Since)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "apikey",
                "value": "{{apikey}}"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_since\": \"2024-04-01T00:00:00Z\",\n  \"p_cursor\": null,\n  \"p_use_source\": false,\n  \"p_lang_prefs\": [\"fr\"],\n  \"p_limit\": 50,\n  \"p_types\": [\"ITI\"],\n  \"p_status\": [\"published\"],\n  \"p_track_format\": \"none\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/list_object_resources_since_fast",
              "host": ["{{base_url}}"],
              "path": ["rpc", "list_object_resources_since_fast"]
            },
            "description": "Synchroniser ce qui a changé depuis un instant T. Robuste pendant les mises à jour. Utilise le keyset pagination."
          },
          "response": [
            {
              "name": "Success Response",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "apikey",
                    "value": "{{apikey}}"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"p_since\": \"2024-04-01T00:00:00Z\"\n}"
                },
                "url": {
                  "raw": "{{base_url}}/rpc/list_object_resources_since_fast",
                  "host": ["{{base_url}}"],
                  "path": ["rpc", "list_object_resources_since_fast"]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n  \"info\": {\n    \"kind\": \"since\",\n    \"language\": \"fr\",\n    \"language_fallbacks\": [\"fr\"],\n    \"since\": \"2024-04-01T00:00:00Z\",\n    \"use_source\": false,\n    \"limit\": 50,\n    \"cursor\": \"<opaque>\",\n    \"next_cursor\": \"<opaque or null>\"\n  },\n  \"data\": []\n}"
            }
          ]
        },
        {
          "name": "List Objects with Validated Changes Since",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "apikey",
                "value": "{{apikey}}"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_since\": \"2024-04-01T00:00:00Z\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/list_objects_with_validated_changes_since",
              "host": ["{{base_url}}"],
              "path": ["rpc", "list_objects_with_validated_changes_since"]
            },
            "description": "Retourne un tableau JSON d'IDs d'objets ayant des changements validés depuis p_since. Accès restreint : service_role/admin."
          },
          "response": [
            {
              "name": "Success Response",
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "[\"HOTRUN0000000001\", \"RESRUN0000000456\"]"
            }
          ]
        }
      ],
      "description": "Endpoints principaux pour récupérer et lister les ressources"
    },
    {
      "name": "3. Advanced Filtering",
      "item": [
        {
          "name": "List with Rich Filters (Page)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "apikey",
                "value": "{{apikey}}"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_cursor\": null,\n  \"p_page_size\": 20,\n  \"p_types\": [\"HER\"],\n  \"p_status\": [\"published\"],\n  \"p_lang_prefs\": [\"fr\"],\n  \"p_track_format\": \"none\",\n  \"p_filters\": {\n    \"amenities_any\": [\"PARKING\", \"WIFI\"],\n    \"pet_accepted\": true,\n    \"within_radius\": {\n      \"lat\": 45.76,\n      \"lon\": 4.84,\n      \"radius_m\": 20000\n    },\n    \"media_types_any\": [\"image\"],\n    \"media_published_only\": true,\n    \"media_must_have_main\": true\n  }\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/list_object_resources_filtered_page",
              "host": ["{{base_url}}"],
              "path": ["rpc", "list_object_resources_filtered_page"]
            },
            "description": "Lister avec filtres riches et pagination par curseur (`p_cursor`, `p_page_size`). Inclut tous les filtres avancés."
          },
          "response": [
            {
              "name": "Success Response",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "apikey",
                    "value": "{{apikey}}"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"p_cursor\": null,\n  \"p_page_size\": 20,\n  \"p_filters\": {\n    \"amenities_any\": [\"PARKING\"]\n  }\n}"
                },
                "url": {
                  "raw": "{{base_url}}/rpc/list_object_resources_filtered_page",
                  "host": ["{{base_url}}"],
                  "path": ["rpc", "list_object_resources_filtered_page"]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n  \"info\": {\n    \"kind\": \"page\",\n    \"language\": \"fr\",\n    \"language_fallbacks\": [\"fr\"],\n    \"page\": 1,\n    \"limit\": 20,\n    \"total\": 25,\n    \"total_pages\": 2,\n    \"filters_applied\": {\n      \"amenities_any\": [\"PARKING\"]\n    }\n  },\n  \"data\": []\n}"
            }
          ]
        },
        {
          "name": "List Ranked Label Search (Explorer Preferred)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "apikey",
                "value": "{{apikey}}"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_cursor\": null,\n  \"p_page_size\": 20,\n  \"p_types\": [\"HOT\"],\n  \"p_status\": [\"published\"],\n  \"p_lang_prefs\": [\"fr\"],\n  \"p_view\": \"card\",\n  \"p_filters\": {\n    \"label_scheme_ranked\": \"LBL_TOURISME_HANDICAP\",\n    \"label_disability_types_any\": [\"motor\"],\n    \"disability_types_any\": [\"motor\"]\n  }\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/list_object_resources_filtered_page",
              "host": ["{{base_url}}"],
              "path": ["rpc", "list_object_resources_filtered_page"]
            },
            "description": "Recherche label classee via l'endpoint Explorer prefere. Les objets certifies arrivent d'abord (`label_match.rank = 0`), puis les objets avec preuves compatibles (`rank = 1`). Pour Tourisme & Handicap, la preuve rank 1 vient des amenagements d'accessibilite; pour les labels durables, elle vient des actions/groupes equivalents."
          }
        },
        {
          "name": "List with Rich Filters (Since)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "apikey",
                "value": "{{apikey}}"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_since\": \"2024-04-01T00:00:00Z\",\n  \"p_cursor\": null,\n  \"p_use_source\": false,\n  \"p_lang_prefs\": [\"fr\"],\n  \"p_limit\": 50,\n  \"p_types\": [\"HER\"],\n  \"p_status\": [\"published\"],\n  \"p_track_format\": \"none\",\n  \"p_filters\": {\n    \"amenities_any\": [\"PARKING\", \"WIFI\"],\n    \"itinerary\": {\n      \"is_loop\": true,\n      \"distance_max_km\": 15,\n      \"practices_any\": [\"hiking\"]\n    },\n    \"within_radius\": {\n      \"lat\": 45.76,\n      \"lon\": 4.84,\n      \"radius_m\": 20000\n    },\n    \"media_types_any\": [\"image\"],\n    \"media_published_only\": true,\n    \"media_must_have_main\": true\n  }\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/list_object_resources_filtered_since_fast",
              "host": ["{{base_url}}"],
              "path": ["rpc", "list_object_resources_filtered_since_fast"]
            },
            "description": "Filtres riches + synchronisation depuis une date. Combine tous les filtres avancés avec le keyset pagination pour une synchronisation robuste."
          },
          "response": [
            {
              "name": "Success Response",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "apikey",
                    "value": "{{apikey}}"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"p_since\": \"2024-04-01T00:00:00Z\",\n  \"p_filters\": {\n    \"amenities_any\": [\"PARKING\"]\n  }\n}"
                },
                "url": {
                  "raw": "{{base_url}}/rpc/list_object_resources_filtered_since_fast",
                  "host": ["{{base_url}}"],
                  "path": ["rpc", "list_object_resources_filtered_since_fast"]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "cookie": [],
              "body": "{\n  \"info\": {\n    \"kind\": \"since\",\n    \"language\": \"fr\",\n    \"language_fallbacks\": [\"fr\"],\n    \"since\": \"2024-04-01T00:00:00Z\",\n    \"use_source\": false,\n    \"limit\": 50,\n    \"cursor\": \"<opaque>\",\n    \"next_cursor\": \"<opaque or null>\",\n    \"filters_applied\": {\n      \"amenities_any\": [\"PARKING\"]\n    }\n  },\n  \"data\": []\n}"
            }
          ]
        }
      ],
      "description": "Endpoints avec filtres avancés pour des recherches complexes"
    },
    {
      "name": "4. Filter Examples",
      "item": [
        {
          "name": "Equipment & Services Filters",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "apikey",
                "value": "{{apikey}}"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_cursor\": null,\n  \"p_page_size\": 20,\n  \"p_types\": [\"HER\"],\n  \"p_status\": [\"published\"],\n  \"p_lang_prefs\": [\"fr\"],\n  \"p_filters\": {\n    \"amenities_any\": [\"PARKING\", \"WIFI\"],\n    \"amenities_all\": [\"RESTAURANT\"],\n    \"amenity_families_any\": [\"ACCOMMODATION\"],\n    \"pet_accepted\": true,\n    \"payment_methods_any\": [\"CREDIT_CARD\", \"CASH\"],\n    \"environment_tags_any\": [\"MOUNTAIN\", \"FOREST\"],\n    \"languages_any\": [\"fr\", \"en\"]\n  }\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/list_object_resources_filtered_page",
              "host": ["{{base_url}}"],
              "path": ["rpc", "list_object_resources_filtered_page"]
            },
            "description": "Exemple de filtres pour équipements et services"
          }
        },
        {
          "name": "Media Filters",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "apikey",
                "value": "{{apikey}}"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_cursor\": null,\n  \"p_page_size\": 20,\n  \"p_types\": [\"HER\", \"ITI\"],\n  \"p_status\": [\"published\"],\n  \"p_lang_prefs\": [\"fr\"],\n  \"p_filters\": {\n    \"media_types_any\": [\"image\", \"video\"],\n    \"media_published_only\": true,\n    \"media_must_have_main\": true\n  }\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/list_object_resources_filtered_page",
              "host": ["{{base_url}}"],
              "path": ["rpc", "list_object_resources_filtered_page"]
            },
            "description": "Exemple de filtres pour les médias"
          }
        },
        {
          "name": "Geolocation Filters",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "apikey",
                "value": "{{apikey}}"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_cursor\": null,\n  \"p_page_size\": 20,\n  \"p_types\": [\"HER\", \"ITI\"],\n  \"p_status\": [\"published\"],\n  \"p_lang_prefs\": [\"fr\"],\n  \"p_filters\": {\n    \"within_radius\": {\n      \"lat\": 45.76,\n      \"lon\": 4.84,\n      \"radius_m\": 20000\n    },\n    \"bbox\": [4.8, 45.7, 4.9, 45.8]\n  }\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/list_object_resources_filtered_page",
              "host": ["{{base_url}}"],
              "path": ["rpc", "list_object_resources_filtered_page"]
            },
            "description": "Exemple de filtres géolocalisation (rayon et bbox)"
          }
        },
        {
          "name": "Itinerary Filters",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "apikey",
                "value": "{{apikey}}"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_cursor\": null,\n  \"p_page_size\": 20,\n  \"p_types\": [\"ITI\"],\n  \"p_status\": [\"published\"],\n  \"p_lang_prefs\": [\"fr\"],\n  \"p_filters\": {\n    \"itinerary\": {\n      \"is_loop\": true,\n      \"difficulty_min\": 1,\n      \"difficulty_max\": 3,\n      \"distance_min_km\": 5,\n      \"distance_max_km\": 15,\n      \"duration_min_h\": 2,\n      \"duration_max_h\": 6,\n      \"practices_any\": [\"hiking\", \"trail_running\"]\n    }\n  }\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/list_object_resources_filtered_page",
              "host": ["{{base_url}}"],
              "path": ["rpc", "list_object_resources_filtered_page"]
            },
            "description": "Exemple de filtres pour les itinéraires"
          }
        },
        {
          "name": "Capacity & Classification Filters",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "apikey",
                "value": "{{apikey}}"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_cursor\": null,\n  \"p_page_size\": 20,\n  \"p_types\": [\"HER\"],\n  \"p_status\": [\"published\"],\n  \"p_lang_prefs\": [\"fr\"],\n  \"p_filters\": {\n    \"capacity_filters\": [\n      {\n        \"code\": \"TOTAL_CAPACITY\",\n        \"min\": 10,\n        \"max\": 100\n      }\n    ],\n    \"classifications_any\": [\n      {\n        \"scheme_code\": \"STARS\",\n        \"value_code\": \"4\"\n      }\n    ],\n    \"tags_any\": [\"luxury\", \"family-friendly\"],\n    \"meeting_room\": {\n      \"min_count\": 1,\n      \"min_area_m2\": 50,\n      \"min_cap_theatre\": 20,\n      \"equipment_any\": [\"PROJECTOR\", \"WHITEBOARD\"]\n    }\n  }\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/list_object_resources_filtered_page",
              "host": ["{{base_url}}"],
              "path": ["rpc", "list_object_resources_filtered_page"]
            },
            "description": "Exemple de filtres pour capacité et classement"
          }
        }
      ],
      "description": "Exemples concrets de tous les types de filtres disponibles"
    },
    {
      "name": "5. Track Data Examples",
      "item": [
        {
          "name": "Get Itinerary with KML Track",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "apikey",
                "value": "{{apikey}}"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_object_id\": \"{{itinerary_id}}\",\n  \"p_lang_prefs\": [\"fr\"],\n  \"p_track_format\": \"kml\",\n  \"p_options\": {\n    \"include_stages\": true,\n    \"stage_color\": \"#FF0000\"\n  }\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/get_object_resource",
              "host": ["{{base_url}}"],
              "path": ["rpc", "get_object_resource"]
            },
            "description": "Récupérer un itinéraire avec son tracé KML et les étapes"
          }
        },
        {
          "name": "Get Itinerary with GPX Track",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Accept",
                "value": "application/json"
              },
              {
                "key": "apikey",
                "value": "{{apikey}}"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_object_id\": \"{{itinerary_id}}\",\n  \"p_lang_prefs\": [\"fr\"],\n  \"p_track_format\": \"gpx\",\n  \"p_options\": {\n    \"include_stages\": false,\n    \"stage_color\": \"#00FF00\"\n  }\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/get_object_resource",
              "host": ["{{base_url}}"],
              "path": ["rpc", "get_object_resource"]
            },
            "description": "Récupérer un itinéraire avec son tracé GPX"
          }
        }
      ],
      "description": "Exemples pour récupérer les données de tracé (KML/GPX)"
    },
    {
      "name": "6. Deep Data",
      "item": [
        {
          "name": "Get Object with Deep Data",
          "request": {
            "method": "POST",
            "header": [
              {"key": "Content-Type", "value": "application/json"},
              {"key": "Accept", "value": "application/json"},
              {"key": "apikey", "value": "{{apikey}}"}
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_object_id\": \"{{object_id}}\",\n  \"p_languages\": [\"fr\", \"en\"]\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/get_object_with_deep_data",
              "host": ["{{base_url}}"],
              "path": ["rpc", "get_object_with_deep_data"]
            },
            "description": "Récupérer un objet avec ses parents, acteurs et organisations en un seul appel"
          }
        },
        {
          "name": "Search Objects with Deep Data",
          "request": {
            "method": "POST",
            "header": [
              {"key": "Content-Type", "value": "application/json"},
              {"key": "Accept", "value": "application/json"},
              {"key": "apikey", "value": "{{apikey}}"}
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_search_term\": \"hôtel spa\",\n  \"p_object_types\": [\"HOT\"],\n  \"p_languages\": [\"fr\"],\n  \"p_limit\": 20\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/search_objects_with_deep_data",
              "host": ["{{base_url}}"],
              "path": ["rpc", "search_objects_with_deep_data"]
            },
            "description": "Rechercher des objets avec inclusion automatique des données liées"
          }
        }
      ],
      "description": "Fonctions Deep Data pour récupérer les objets avec leurs relations en un seul appel"
    },
    {
      "name": "7. Search & Discovery",
      "item": [
        {
          "name": "Search Objects by Label",
          "request": {
            "method": "POST",
            "header": [
              {"key": "Content-Type", "value": "application/json"},
              {"key": "Accept", "value": "application/json"},
              {"key": "apikey", "value": "{{apikey}}"}
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_label_value_id\": \"uuid-ecolabel-europeen\",\n  \"p_include_partial\": true,\n  \"p_lang_prefs\": [\"fr\"],\n  \"p_limit\": 20\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/search_objects_by_label",
              "host": ["{{base_url}}"],
              "path": ["rpc", "search_objects_by_label"]
            },
            "description": "Compatibilite/specialise: rechercher des objets par valeur de label avec correspondances partielles de durabilite. Pour l'Explorer, preferer list_object_resources_filtered_page avec p_filters.label_scheme_ranked afin de recevoir label_match et l'ordre certifie puis preuves compatibles."
          }
        },
        {
          "name": "List Objects Map View",
          "request": {
            "method": "POST",
            "header": [
              {"key": "Content-Type", "value": "application/json"},
              {"key": "Accept", "value": "application/json"},
              {"key": "apikey", "value": "{{apikey}}"}
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_types\": [\"HOT\", \"RES\"],\n  \"p_status\": [\"published\"],\n  \"p_limit\": 500\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/list_objects_map_view",
              "host": ["{{base_url}}"],
              "path": ["rpc", "list_objects_map_view"]
            },
            "description": "Vue carte allégée avec payload minimal (coordonnées, nom, type, image)"
          }
        },
        {
          "name": "Search Restaurants by Cuisine",
          "request": {
            "method": "POST",
            "header": [
              {"key": "Content-Type", "value": "application/json"},
              {"key": "Accept", "value": "application/json"},
              {"key": "apikey", "value": "{{apikey}}"}
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_cuisine_types\": [\"local\", \"veggie\"],\n  \"p_lang_prefs\": [\"fr\"],\n  \"p_limit\": 20\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/search_restaurants_by_cuisine",
              "host": ["{{base_url}}"],
              "path": ["rpc", "search_restaurants_by_cuisine"]
            },
            "description": "Recherche spécialisée de restaurants par types de cuisine"
          }
        }
      ],
      "description": "Fonctions de recherche et découverte (labels, carte, cuisine)"
    },
    {
      "name": "8. Media",
      "item": [
        {
          "name": "Get Media for Web",
          "request": {
            "method": "POST",
            "header": [
              {"key": "Content-Type", "value": "application/json"},
              {"key": "Accept", "value": "application/json"},
              {"key": "apikey", "value": "{{apikey}}"}
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_object_id\": \"{{object_id}}\",\n  \"p_preferred_tags\": [\"facade\", \"interieur\", \"cuisine\"],\n  \"p_lang_prefs\": [\"fr\"],\n  \"p_limit\": 20\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/get_media_for_web",
              "host": ["{{base_url}}"],
              "path": ["rpc", "get_media_for_web"]
            },
            "description": "Récupérer les médias filtrés pour le web (exclut internes/brouillons, sélection intelligente de l'image principale)"
          }
        }
      ],
      "description": "Gestion des médias avec filtrage et sélection intelligente"
    },
    {
      "name": "9. Reviews & Room Types",
      "item": [
        {
          "name": "Get Object Reviews",
          "request": {
            "method": "POST",
            "header": [
              {"key": "Content-Type", "value": "application/json"},
              {"key": "Accept", "value": "application/json"},
              {"key": "apikey", "value": "{{apikey}}"}
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_object_id\": \"{{object_id}}\",\n  \"p_limit\": 10,\n  \"p_offset\": 0,\n  \"p_lang_prefs\": [\"fr\"]\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/get_object_reviews",
              "host": ["{{base_url}}"],
              "path": ["rpc", "get_object_reviews"]
            },
            "description": "Récupérer les avis avec agrégats (note moyenne, nombre total)"
          }
        },
        {
          "name": "Get Object Room Types",
          "request": {
            "method": "POST",
            "header": [
              {"key": "Content-Type", "value": "application/json"},
              {"key": "Accept", "value": "application/json"},
              {"key": "apikey", "value": "{{apikey}}"}
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_object_id\": \"{{object_id}}\",\n  \"p_lang_prefs\": [\"fr\"]\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/get_object_room_types",
              "host": ["{{base_url}}"],
              "path": ["rpc", "get_object_room_types"]
            },
            "description": "Récupérer les types de chambres avec équipements, capacités et tarifs"
          }
        }
      ],
      "description": "Avis externes et types de chambres pour hébergements"
    },
    {
      "name": "10. Promotions",
      "item": [
        {
          "name": "Validate Promotion Code",
          "request": {
            "method": "POST",
            "header": [
              {"key": "Content-Type", "value": "application/json"},
              {"key": "Accept", "value": "application/json"},
              {"key": "apikey", "value": "{{apikey}}"}
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_code\": \"SUMMER2026\",\n  \"p_object_id\": \"{{object_id}}\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/validate_promotion_code",
              "host": ["{{base_url}}"],
              "path": ["rpc", "validate_promotion_code"]
            },
            "description": "Valider un code promotionnel avec vérification temporelle et applicabilité"
          }
        }
      ],
      "description": "Validation de codes promotionnels"
    },
    {
      "name": "11. Track & GPX Export",
      "item": [
        {
          "name": "Export Itinerary GPX",
          "request": {
            "method": "POST",
            "header": [
              {"key": "Content-Type", "value": "application/json"},
              {"key": "Accept", "value": "application/json"},
              {"key": "apikey", "value": "{{apikey}}"}
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_object_id\": \"{{itinerary_id}}\",\n  \"p_include_stages\": true,\n  \"p_include_metadata\": true\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/export_itinerary_gpx",
              "host": ["{{base_url}}"],
              "path": ["rpc", "export_itinerary_gpx"]
            },
            "description": "Export GPX complet avec métadonnées et waypoints"
          }
        },
        {
          "name": "Export Itineraries GPX Batch",
          "request": {
            "method": "POST",
            "header": [
              {"key": "Content-Type", "value": "application/json"},
              {"key": "Accept", "value": "application/json"},
              {"key": "apikey", "value": "{{apikey}}"}
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_object_ids\": [\"ITI123\", \"ITI456\"],\n  \"p_include_stages\": true\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/export_itineraries_gpx_batch",
              "host": ["{{base_url}}"],
              "path": ["rpc", "export_itineraries_gpx_batch"]
            },
            "description": "Export GPX batch pour plusieurs itinéraires"
          }
        },
        {
          "name": "Get Itinerary Track GeoJSON",
          "request": {
            "method": "POST",
            "header": [
              {"key": "Content-Type", "value": "application/json"},
              {"key": "Accept", "value": "application/json"},
              {"key": "apikey", "value": "{{apikey}}"}
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_object_id\": \"{{itinerary_id}}\",\n  \"p_simplify\": false,\n  \"p_tolerance\": 0.0001\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/get_itinerary_track_geojson",
              "host": ["{{base_url}}"],
              "path": ["rpc", "get_itinerary_track_geojson"]
            },
            "description": "Tracé GeoJSON FeatureCollection (compatible Leaflet, Mapbox)"
          }
        }
      ],
      "description": "Export de traces GPX et GeoJSON pour itinéraires"
    },
    {
      "name": "12. Legal System",
      "item": [
        {
          "name": "Add Legal Record",
          "request": {
            "method": "POST",
            "header": [
              {"key": "Content-Type", "value": "application/json"},
              {"key": "Accept", "value": "application/json"},
              {"key": "apikey", "value": "{{apikey}}"}
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_object_id\": \"{{object_id}}\",\n  \"p_type_code\": \"ASSURANCE_RC\",\n  \"p_value\": {\n    \"policy_number\": \"RC-2024-12345\",\n    \"insurer\": \"Allianz\",\n    \"coverage_amount\": 5000000\n  },\n  \"p_valid_from\": \"2024-01-01\",\n  \"p_valid_to\": \"2024-12-31\",\n  \"p_validity_mode\": \"fixed_end_date\",\n  \"p_status\": \"active\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/add_legal_record",
              "host": ["{{base_url}}"],
              "path": ["rpc", "add_legal_record"]
            },
            "description": "Ajouter un enregistrement juridique (assurance, licence, certification, etc.)"
          }
        },
        {
          "name": "Get Object Legal Data",
          "request": {
            "method": "POST",
            "header": [
              {"key": "Content-Type", "value": "application/json"},
              {"key": "Accept", "value": "application/json"},
              {"key": "apikey", "value": "{{apikey}}"}
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_object_id\": \"{{object_id}}\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/get_object_legal_data",
              "host": ["{{base_url}}"],
              "path": ["rpc", "get_object_legal_data"]
            },
            "description": "Récupérer tous les enregistrements juridiques d'un objet"
          }
        },
        {
          "name": "Get Object Legal Compliance",
          "request": {
            "method": "POST",
            "header": [
              {"key": "Content-Type", "value": "application/json"},
              {"key": "Accept", "value": "application/json"},
              {"key": "apikey", "value": "{{apikey}}"}
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_object_id\": \"{{object_id}}\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/get_object_legal_compliance",
              "host": ["{{base_url}}"],
              "path": ["rpc", "get_object_legal_compliance"]
            },
            "description": "Vérifier la conformité juridique (documents manquants, expirés)"
          }
        },
        {
          "name": "Get Expiring Legal Records",
          "request": {
            "method": "POST",
            "header": [
              {"key": "Content-Type", "value": "application/json"},
              {"key": "Accept", "value": "application/json"},
              {"key": "apikey", "value": "{{apikey}}"}
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_days_ahead\": 30,\n  \"p_object_types\": [\"HOT\", \"RES\"],\n  \"p_legal_types\": null\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/get_expiring_legal_records_api",
              "host": ["{{base_url}}"],
              "path": ["rpc", "get_expiring_legal_records_api"]
            },
            "description": "Lister les enregistrements juridiques arrivant à expiration"
          }
        },
        {
          "name": "Request Legal Document",
          "request": {
            "method": "POST",
            "header": [
              {"key": "Content-Type", "value": "application/json"},
              {"key": "Accept", "value": "application/json"},
              {"key": "apikey", "value": "{{apikey}}"}
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_legal_id\": \"uuid-legal-record\",\n  \"p_requested_at\": \"2024-01-15T10:00:00Z\"\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/request_legal_document",
              "host": ["{{base_url}}"],
              "path": ["rpc", "request_legal_document"]
            },
            "description": "Marquer un document comme demandé (workflow)"
          }
        },
        {
          "name": "Get Pending Document Requests",
          "request": {
            "method": "POST",
            "header": [
              {"key": "Content-Type", "value": "application/json"},
              {"key": "Accept", "value": "application/json"},
              {"key": "apikey", "value": "{{apikey}}"}
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"p_object_id\": null,\n  \"p_type_codes\": null\n}"
            },
            "url": {
              "raw": "{{base_url}}/rpc/get_pending_document_requests_api",
              "host": ["{{base_url}}"],
              "path": ["rpc", "get_pending_document_requests_api"]
            },
            "description": "Lister les demandes de documents en attente"
          }
        }
      ],
      "description": "Système juridique complet : CRUD, conformité, expirations, workflow documentaire"
    },
    {
      "name": "13. API Publique Partenaire (/api/public/*)",
      "description": "Passerelle TIERCE authentifiée par clé partenaire (`Authorization: Bearer bk_live_…`, émise par l'OTI). Contrat stable versionné (`meta.contract_version` + header `X-Bertel-Api-Version`), enveloppe `{ meta, data }`, fiches PUBLIÉES uniquement. Utilisez uniquement votre clé partenaire `bk_live_…` — aucun autre identifiant n'est accepté. Variables : `public_base_url` (URL de l'app), `partner_key` (clé `bk_live_…`). Lancer « Lister les fiches publiées » en premier : il remplit `object_id` pour les requêtes de détail.",
      "item": [
        {
          "name": "Lister les fiches publiées",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const d = pm.response.json();",
                  "if (d.data && d.data.length > 0) { pm.collectionVariables.set('object_id', d.data[0].id); }",
                  "pm.test('enveloppe { meta, data }', function () { pm.expect(d).to.have.property('meta'); pm.expect(d).to.have.property('data'); });"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [
              {"key": "Accept", "value": "application/json"},
              {"key": "Authorization", "value": "Bearer {{partner_key}}", "description": "Clé partenaire bk_live_…"}
            ],
            "url": {
              "raw": "{{public_base_url}}/api/public/objects?page_size=20",
              "host": ["{{public_base_url}}"],
              "path": ["api", "public", "objects"],
              "query": [
                {"key": "page_size", "value": "20"},
                {"key": "types", "value": "HOT,RES", "disabled": true},
                {"key": "search", "value": "", "disabled": true},
                {"key": "format", "value": "datatourisme", "disabled": true, "description": "jsonld | datatourisme | apidae | tourinsoft — chaque fiche de la page porte son document pivot sous data[i].<profil> (I4c)"}
              ]
            },
            "description": "Page de fiches PUBLIÉES (curseur `cursor`, `page_size` 1–200, `types` csv, `search`, `lang`). Avec `format=<profil>` (jsonld/datatourisme/apidae/tourinsoft), chaque fiche de la page porte en plus son document pivot sous une clé additive `data[i].<profil>` — même pagination, un appel par page (I4c). Stocke automatiquement `object_id = data[0].id` pour les requêtes suivantes."
          }
        },
        {
          "name": "Lister les fiches publiées (fiches complètes, view=full)",
          "request": {
            "method": "GET",
            "header": [
              {"key": "Accept", "value": "application/json"},
              {"key": "Authorization", "value": "Bearer {{partner_key}}", "description": "Clé partenaire bk_live_…"}
            ],
            "url": {
              "raw": "{{public_base_url}}/api/public/objects?view=full&page_size=100&track=gpx",
              "host": ["{{public_base_url}}"],
              "path": ["api", "public", "objects"],
              "query": [
                {"key": "view", "value": "full", "description": "Fiche complète par objet (identique au détail /objects/{id})"},
                {"key": "page_size", "value": "100", "description": "Borné à 100 en mode full (défaut 25)"},
                {"key": "track", "value": "gpx", "description": "Optionnel : blob GPX/KML des itinéraires (le GeoJSON est natif)"},
                {"key": "types", "value": "ITI", "disabled": true},
                {"key": "format", "value": "datatourisme", "disabled": true, "description": "Orthogonal : ajoute aussi le document pivot par fiche"}
              ]
            },
            "description": "Comme « Lister les fiches publiées » mais chaque objet est la FICHE COMPLÈTE (photos, descriptions, équipements, classements, chambres, horaires, tracé GeoJSON natif) — même contenu que GET /objects/{id}, hors CRM. Mode `full` borné à 100/page. `track=gpx|kml` ajoute le blob de tracé des itinéraires."
          }
        },
        {
          "name": "Récupérer une fiche publiée",
          "request": {
            "method": "GET",
            "header": [
              {"key": "Accept", "value": "application/json"},
              {"key": "Authorization", "value": "Bearer {{partner_key}}"}
            ],
            "url": {
              "raw": "{{public_base_url}}/api/public/objects/{{object_id}}",
              "host": ["{{public_base_url}}"],
              "path": ["api", "public", "objects", "{{object_id}}"]
            },
            "description": "Ressource complète d'une fiche PUBLIÉE. Un id inconnu ou non publié → 404 (indistinguable, pas de fuite de brouillon)."
          },
          "response": [
            {
              "name": "Fiche publiée — exemple réel",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/json"
                  },
                  {
                    "key": "Authorization",
                    "value": "Bearer {{partner_key}}"
                  }
                ],
                "url": {
                  "raw": "{{public_base_url}}/api/public/objects/{{object_id}}",
                  "host": [
                    "{{public_base_url}}"
                  ],
                  "path": [
                    "api",
                    "public",
                    "objects",
                    "{{object_id}}"
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                },
                {
                  "key": "X-Bertel-Api-Version",
                  "value": "1.0.0"
                }
              ],
              "cookie": [],
              "body": "{\n  \"meta\": {\n    \"contract_version\": \"1.0.0\"\n  },\n  \"data\": {\n    \"id\": \"RESRUN00000000NQ\",\n    \"fma\": [],\n    \"name\": \"Ferme Lebon Papillon\",\n    \"tags\": [\n      {\n        \"icon\": \"heart\",\n        \"name\": \"Bien-être\",\n        \"slug\": \"wellness\",\n        \"color\": \"#ec4899\",\n        \"icon_url\": null\n      },\n      {\n        \"icon\": \"shopping-bag\",\n        \"name\": \"Boutique\",\n        \"slug\": \"shopping\",\n        \"color\": \"#14b8a6\",\n        \"icon_url\": null\n      },\n      {\n        \"icon\": \"utensils\",\n        \"name\": \"Cuisine\",\n        \"slug\": \"food\",\n        \"color\": \"#f97316\",\n        \"icon_url\": null\n      },\n      {\n        \"icon\": \"wheat\",\n        \"name\": \"Ferme et agrotourisme\",\n        \"slug\": \"farm\",\n        \"color\": \"#65a30d\",\n        \"icon_url\": null\n      },\n      {\n        \"icon\": \"binoculars\",\n        \"name\": \"Panorama\",\n        \"slug\": \"panorama\",\n        \"color\": \"#0ea5e9\",\n        \"icon_url\": null\n      },\n      {\n        \"icon\": \"mountain\",\n        \"name\": \"Plein air\",\n        \"slug\": \"outdoor\",\n        \"color\": \"#16a34a\",\n        \"icon_url\": null\n      }\n    ],\n    \"type\": \"RES\",\n    \"media\": [\n      {\n        \"id\": \"69165d0f-5c8e-4527-8847-0f88ca99c9f2\",\n        \"url\": \"https://ryycrdhlkmzpxwwwwupy.supabase.co/storage/v1/object/public/old_media/daa43f48.Path.112724.webp\",\n        \"tags\": [],\n        \"title\": null,\n        \"width\": null,\n        \"credit\": null,\n        \"height\": null,\n        \"is_main\": true,\n        \"icon_url\": null,\n        \"position\": 0,\n        \"type_code\": \"photo\",\n        \"type_name\": \"Photo\",\n        \"visibility\": null,\n        \"description\": null,\n        \"type_description\": \"Photographies officielles\"\n      },\n      {\n        \"id\": \"16234d34-096e-4f36-a6d2-d095ad846a7c\",\n        \"url\": \"https://ryycrdhlkmzpxwwwwupy.supabase.co/storage/v1/object/public/old_media/f0bb6beb.Path.055711.jpg\",\n        \"tags\": [],\n        \"title\": null,\n        \"width\": null,\n        \"credit\": null,\n        \"height\": null,\n        \"is_main\": false,\n        \"icon_url\": null,\n        \"position\": 0,\n        \"type_code\": \"photo\",\n        \"type_name\": \"Photo\",\n        \"visibility\": null,\n        \"description\": null,\n        \"type_description\": \"Photographies officielles\"\n      },\n      {\n        \"id\": \"1e000a40-2da7-4372-b3c6-fe8bd1fd47c5\",\n        \"url\": \"https://ryycrdhlkmzpxwwwwupy.supabase.co/storage/v1/object/public/old_media/ab362207.Path.112625.webp\",\n        \"tags\": [],\n        \"title\": null,\n        \"width\": null,\n        \"credit\": null,\n        \"height\": null,\n        \"is_main\": false,\n        \"icon_url\": null,\n        \"position\": 0,\n        \"type_code\": \"photo\",\n        \"type_name\": \"Photo\",\n        \"visibility\": null,\n        \"description\": null,\n        \"type_description\": \"Photographies officielles\"\n      }\n    ],\n    \"menus\": [],\n    \"actors\": [],\n    \"places\": [],\n    \"prices\": [],\n    \"render\": {\n      \"lang\": \"fr\",\n      \"locale\": \"fr-FR\",\n      \"version\": \"1.0\",\n      \"timezone\": \"UTC\",\n      \"actor_lines\": [\n        \"Mme Murielle Lebon (Exploitant)\"\n      ],\n      \"event_lines\": [],\n      \"legal_lines\": [],\n      \"media_lines\": [\n        \"Photo\",\n        \"Photo\",\n        \"Photo\",\n        \"Photo\",\n        \"Photo\",\n        \"Photo\",\n        \"Photo\",\n        \"Photo\",\n        \"Photo\",\n        \"Photo\",\n        \"Photo\",\n        \"Photo\"\n      ],\n      \"price_lines\": [],\n      \"amenity_lines\": [\n        \"Parking (Parking)\",\n        \"Bar (Services)\",\n        \"Restaurant (Services)\"\n      ],\n      \"contact_lines\": [\n        \"Mobile : 0692 88 27 04\",\n        \"Email : fermelebonpapillon@gmail.com\",\n        \"Website : http://www.fermelebon.fr\"\n      ],\n      \"capacity_lines\": [\n        \"20 seat Asientos\"\n      ],\n      \"discount_lines\": [],\n      \"taxonomy_lines\": [\n        \"Taxonomie RES : Table d'hôtes > Table d'hôte\"\n      ],\n      \"menu_item_lines\": [],\n      \"meeting_room_lines\": [],\n      \"classification_lines\": [\n        \"Accueil Paysan : Restauration paysanne (granted)\"\n      ],\n      \"sustainability_lines\": [],\n      \"event_occurrence_lines\": []\n    },\n    \"status\": \"published\",\n    \"address\": {\n      \"city\": \"Le Tampon\",\n      \"address1\": \"90 Chemin des Papillons Pont d'Yves Tampon\",\n      \"address2\": null,\n      \"address3\": null,\n      \"lieu_dit\": \"Bras de Pontho\",\n      \"postcode\": \"97430\",\n      \"direction\": \"De Saint-Pierre RN3 jusqu'au RP du 17ème km, prendre à gauche au petit RP, prendre le chemin de la Salette point de repère le champ d'agrume à droite, tourner au chemin Tiguet puis au radier le chemin Papillon, panneau Ferme Lebon Papillon à gauche, suivre le panneau. \\nDepuis Saint-Benoît RN3 jusqu'au RP du 17ème km prendre à droite, même itinéraire.\",\n      \"code_insee\": null,\n      \"direction_md\": \"De Saint-Pierre RN3 jusqu'au RP du 17ème km, prendre à gauche au petit RP, prendre le chemin de la Salette point de repère le champ d'agrume à droite, tourner au chemin Tiguet puis au radier le chemin Papillon, panneau Ferme Lebon Papillon à gauche, suivre le panneau. \\nDepuis Saint-Benoît RN3 jusqu'au RP du 17ème km prendre à droite, même itinéraire.\",\n      \"address1_suite\": null\n    },\n    \"origins\": [\n      {\n        \"created_at\": \"2026-05-01T09:24:21.93396+00:00\",\n        \"updated_at\": \"2026-05-01T09:24:21.93396+00:00\",\n        \"source_system\": \"berta_v2_csv_export\",\n        \"import_batch_id\": null,\n        \"source_object_id\": \"recR99OmSXnqpQRCv\",\n        \"first_imported_at\": \"2026-05-01T09:24:21.93396+00:00\"\n      }\n    ],\n    \"capacity\": [\n      {\n        \"unit\": \"seat\",\n        \"value\": 20,\n        \"icon_url\": null,\n        \"metric_code\": \"seats\",\n        \"metric_name\": \"Places assises\",\n        \"metric_description\": \"Nombre de sièges assis\"\n      }\n    ],\n    \"contacts\": [\n      {\n        \"role\": null,\n        \"value\": \"0692 88 27 04\",\n        \"icon_url\": null,\n        \"position\": 1,\n        \"is_public\": true,\n        \"kind_code\": \"mobile\",\n        \"kind_name\": \"Mobile\",\n        \"is_primary\": true,\n        \"kind_description\": \"Numéro de portable pour joindre l'établissement\"\n      },\n      {\n        \"role\": null,\n        \"value\": \"fermelebonpapillon@gmail.com\",\n        \"icon_url\": null,\n        \"position\": 4,\n        \"is_public\": true,\n        \"kind_code\": \"email\",\n        \"kind_name\": \"Email\",\n        \"is_primary\": true,\n        \"kind_description\": \"Adresse électronique principale\"\n      },\n      {\n        \"role\": null,\n        \"value\": \"http://www.fermelebon.fr\",\n        \"icon_url\": null,\n        \"position\": 5,\n        \"is_public\": true,\n        \"kind_code\": \"website\",\n        \"kind_name\": \"Site web\",\n        \"is_primary\": true,\n        \"kind_description\": \"URL du site officiel\"\n      }\n    ],\n    \"location\": {\n      \"geometry\": {\n        \"type\": \"Point\",\n        \"coordinates\": [\n          55.516476,\n          -21.230521\n        ]\n      },\n      \"latitude\": -21.230521,\n      \"longitude\": 55.516476,\n      \"altitude_m\": null\n    },\n    \"position\": 0,\n    \"taxonomy\": {\n      \"domains\": [\n        {\n          \"path\": [\n            {\n              \"id\": \"45071891-a299-4183-a673-e3d6dfb8b3eb\",\n              \"code\": \"table_d_hotes\",\n              \"name\": \"Table d'hôtes\",\n              \"depth\": 0,\n              \"description\": \"Table d'hôtes\"\n            },\n            {\n              \"id\": \"4b32363d-64d9-46b7-8098-44c9a1d09a2b\",\n              \"code\": \"table_d_hote\",\n              \"name\": \"Table d'hôte\",\n              \"depth\": 1,\n              \"description\": \"Table d'hôte\"\n            }\n          ],\n          \"domain\": \"taxonomy_res\",\n          \"source\": \"old_data_enrichment_20260512\",\n          \"updated_at\": \"2026-05-14T08:49:19.006951+00:00\",\n          \"domain_name\": \"Taxonomie RES\",\n          \"object_type\": \"RES\",\n          \"assigned_node\": {\n            \"id\": \"4b32363d-64d9-46b7-8098-44c9a1d09a2b\",\n            \"code\": \"table_d_hote\",\n            \"name\": \"Table d'hôte\",\n            \"depth\": 1,\n            \"description\": \"Table d'hôte\"\n          }\n        }\n      ]\n    },\n    \"allergens\": [],\n    \"amenities\": [\n      {\n        \"code\": \"parking\",\n        \"name\": \"Parking\",\n        \"family\": {\n          \"code\": \"parking\",\n          \"name\": \"Parking\",\n          \"icon_url\": null\n        },\n        \"icon_url\": null,\n        \"disability_types\": null\n      },\n      {\n        \"code\": \"bar\",\n        \"name\": \"Bar\",\n        \"family\": {\n          \"code\": \"services\",\n          \"name\": \"Services\",\n          \"icon_url\": null\n        },\n        \"icon_url\": null,\n        \"disability_types\": null\n      },\n      {\n        \"code\": \"restaurant\",\n        \"name\": \"Restaurant\",\n        \"family\": {\n          \"code\": \"services\",\n          \"name\": \"Services\",\n          \"icon_url\": null\n        },\n        \"icon_url\": null,\n        \"disability_types\": null\n      }\n    ],\n    \"discounts\": [],\n    \"languages\": [\n      {\n        \"code\": \"rcf\",\n        \"name\": \"Créole réunionnais\",\n        \"level\": null\n      },\n      {\n        \"code\": \"fr\",\n        \"name\": \"Français\",\n        \"level\": null\n      }\n    ],\n    \"org_links\": [\n      {\n        \"note\": \"Publisher link from Berta v2 Old_data import\",\n        \"role_id\": \"8b0c1597-1bf7-4287-b764-2884a4e9b1a2\",\n        \"created_at\": \"2026-05-01T09:24:21.93396+00:00\",\n        \"is_primary\": true,\n        \"updated_at\": \"2026-05-01T09:24:21.93396+00:00\",\n        \"org_object_id\": \"ORGRUN000000000B\"\n      }\n    ],\n    \"created_at\": \"2026-05-01T09:24:21.93396+00:00\",\n    \"is_editing\": false,\n    \"promotions\": [],\n    \"room_types\": [],\n    \"updated_at\": \"2026-06-04T15:29:30.03687+00:00\",\n    \"visibility\": \"public\",\n    \"description\": \"Spécialités : poulet songe, poulet papaye sont proposés à la table paysanne. Découvrir ou redécouvrir les produits lontan avec Murielle et David.\\nDans une ambiance calme et verdoyante, fraîcheur garantie avec les produits maraîchers cultivés sur place en agriculture bio.\\nOuvert tous les jours midi et soir sur réservation 2 jours avant (min de 5 personnes).\",\n    \"object_zone\": [],\n    \"region_code\": \"RUN\",\n    \"descriptions\": [\n      {\n        \"id\": \"719b7ee8-f3e2-4fc0-820c-6b158fa78d65\",\n        \"position\": 0,\n        \"created_at\": \"2026-05-01T09:24:21.93396+00:00\",\n        \"updated_at\": \"2026-06-04T15:29:30.03687+00:00\",\n        \"visibility\": \"public\",\n        \"description\": \"Spécialités : poulet songe, poulet papaye sont proposés à la table paysanne. Découvrir ou redécouvrir les produits lontan avec Murielle et David.\\nDans une ambiance calme et verdoyante, fraîcheur garantie avec les produits maraîchers cultivés sur place en agriculture bio.\\nOuvert tous les jours midi et soir sur réservation 2 jours avant (min de 5 personnes).\",\n        \"description_md\": \"Spécialités : poulet songe, poulet papaye sont proposés à la table paysanne. Découvrir ou redécouvrir les produits lontan avec Murielle et David.\\nDans une ambiance calme et verdoyante, fraîcheur garantie avec les produits maraîchers cultivés sur place en agriculture bio.\\nOuvert tous les jours midi et soir sur réservation 2 jours avant (min de 5 personnes).\",\n        \"description_chapo\": \"Située au Tampon, Ferme Lebon Papillon dispose d'une table d'hôte labellisée Accueil Paysan qui propose une cuisine créole traditionnelle.\",\n        \"sanitary_measures\": null,\n        \"description_mobile\": null,\n        \"description_adapted\": null,\n        \"description_edition\": null,\n        \"description_chapo_md\": \"Située au Tampon, Ferme Lebon Papillon dispose d'une table d'hôte labellisée Accueil Paysan qui propose une cuisine créole traditionnelle.\",\n        \"description_mobile_md\": null,\n        \"description_adapted_md\": null,\n        \"description_edition_md\": null,\n        \"description_offre_hors_zone\": null\n      }\n    ],\n    \"dietary_tags\": [],\n    \"external_ids\": [\n      {\n        \"id\": \"766df472-c16a-4d1f-8748-0dd40a98c3a0\",\n        \"created_at\": \"2026-05-01T09:24:21.93396+00:00\",\n        \"updated_at\": \"2026-05-01T09:24:21.93396+00:00\",\n        \"external_id\": \"recR99OmSXnqpQRCv\",\n        \"source_system\": \"berta_v2_csv_export\",\n        \"last_synced_at\": \"2026-05-01T09:24:21.93396+00:00\",\n        \"organization_object_id\": \"ORGRUN000000000B\"\n      }\n    ],\n    \"web_channels\": [],\n    \"cuisine_types\": [],\n    \"legal_records\": [],\n    \"meeting_rooms\": [],\n    \"opening_times\": {\n      \"periods_current\": [],\n      \"periods_next_year\": []\n    },\n    \"description_md\": \"Spécialités : poulet songe, poulet papaye sont proposés à la table paysanne. Découvrir ou redécouvrir les produits lontan avec Murielle et David.\\nDans une ambiance calme et verdoyante, fraîcheur garantie avec les produits maraîchers cultivés sur place en agriculture bio.\\nOuvert tous les jours midi et soir sur réservation 2 jours avant (min de 5 personnes).\",\n    \"group_policies\": [],\n    \"menu_documents\": [],\n    \"classifications\": [\n      {\n        \"value\": \"restauration\",\n        \"scheme\": \"accueil_paysan\",\n        \"status\": \"granted\",\n        \"awarded_at\": null,\n        \"value_name\": \"Restauration paysanne\",\n        \"scheme_name\": \"Accueil Paysan\",\n        \"valid_until\": null,\n        \"disability_types_covered\": []\n      }\n    ],\n    \"fma_occurrences\": [],\n    \"payment_methods\": [\n      {\n        \"code\": \"cheque\",\n        \"name\": \"Chèque\",\n        \"icon_url\": null,\n        \"description\": \"Chèques bancaires\"\n      },\n      {\n        \"code\": \"especes\",\n        \"name\": \"Espèces\",\n        \"icon_url\": null,\n        \"description\": \"Paiement en liquide\"\n      }\n    ],\n    \"environment_tags\": [\n      {\n        \"code\": \"calme\",\n        \"name\": \"Calme\",\n        \"icon_url\": null,\n        \"description\": \"Environnement calme\"\n      },\n      {\n        \"code\": \"rural\",\n        \"name\": \"Rural\",\n        \"icon_url\": null,\n        \"description\": \"Village ou hameau rural\"\n      },\n      {\n        \"code\": \"vue_panoramique\",\n        \"name\": \"Vue panoramique\",\n        \"icon_url\": null,\n        \"description\": \"Vue panoramique exceptionnelle\"\n      }\n    ],\n    \"description_chapo\": \"Située au Tampon, Ferme Lebon Papillon dispose d'une table d'hôte labellisée Accueil Paysan qui propose une cuisine créole traditionnelle.\",\n    \"incoming_relations\": [],\n    \"outgoing_relations\": [],\n    \"accessibility_labels\": [],\n    \"description_chapo_md\": \"Située au Tampon, Ferme Lebon Papillon dispose d'une table d'hôte labellisée Accueil Paysan qui propose une cuisine créole traditionnelle.\",\n    \"commercial_visibility\": \"active\",\n    \"sustainability_labels\": [],\n    \"sustainability_actions\": [],\n    \"sustainability_action_labels\": []\n  }\n}"
            }
          ]
        },
        {
          "name": "Fiche + JSON-LD schema.org (I4 · ?format=jsonld)",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const d = pm.response.json();",
                  "pm.test('bloc additif data.jsonld présent', function () { pm.expect(d.data).to.have.property('jsonld'); });",
                  "pm.test('document schema.org', function () { pm.expect(d.data.jsonld['@context']).to.eql('https://schema.org'); pm.expect(d.data.jsonld).to.have.property('@type'); });"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [
              {"key": "Accept", "value": "application/json"},
              {"key": "Authorization", "value": "Bearer {{partner_key}}"}
            ],
            "url": {
              "raw": "{{public_base_url}}/api/public/objects/{{object_id}}?format=jsonld",
              "host": ["{{public_base_url}}"],
              "path": ["api", "public", "objects", "{{object_id}}"],
              "query": [{"key": "format", "value": "jsonld"}]
            },
            "description": "Ajoute un bloc ADDITIF `data.jsonld` = document JSON-LD schema.org (`@type` selon le type d'objet, crosswalk piloté par table côté serveur `ref_interop_crosswalk`). Directement réutilisable pour le SEO / l'interopérabilité (à injecter dans un `<script type=\"application/ld+json\">`). Orthogonal à `lang` ; les clés de base ne sont jamais mutées. Contacts / médias / réseaux PUBLICS uniquement ; texte propre (Markdown neutralisé)."
          },
          "response": [
            {
              "name": "Exemple — Restaurant",
              "originalRequest": {
                "method": "GET",
                "header": [{"key": "Authorization", "value": "Bearer {{partner_key}}"}],
                "url": {
                  "raw": "{{public_base_url}}/api/public/objects/{{object_id}}?format=jsonld",
                  "host": ["{{public_base_url}}"],
                  "path": ["api", "public", "objects", "{{object_id}}"],
                  "query": [{"key": "format", "value": "jsonld"}]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {"key": "Content-Type", "value": "application/json"},
                {"key": "X-Bertel-Api-Version", "value": "1.0.0"}
              ],
              "cookie": [],
              "body": "{\n  \"meta\": { \"contract_version\": \"1.0.0\" },\n  \"data\": {\n    \"id\": \"RESRUN00000000XK\",\n    \"name\": \"Le Macabit\",\n    \"jsonld\": {\n      \"@context\": \"https://schema.org\",\n      \"@type\": \"Restaurant\",\n      \"@id\": \"urn:bertel:object:RESRUN00000000XK\",\n      \"identifier\": \"RESRUN00000000XK\",\n      \"name\": \"Le Macabit\",\n      \"description\": \"Le restaurant Le Macabit se situe dans le Sud sauvage, à Saint-Philippe…\",\n      \"url\": \"https://www.lemaccabit.re/\",\n      \"telephone\": \"0262 37 15 30\",\n      \"email\": \"lemacabit97442@gmail.com\",\n      \"image\": \"https://…/cover.jpg\",\n      \"address\": {\n        \"@type\": \"PostalAddress\",\n        \"streetAddress\": \"76 Route Nationale 2 Ravine Ango\",\n        \"postalCode\": \"97442\",\n        \"addressLocality\": \"Saint-Philippe\",\n        \"addressRegion\": \"La Réunion\",\n        \"addressCountry\": \"FR\"\n      },\n      \"geo\": { \"@type\": \"GeoCoordinates\", \"latitude\": -21.3488, \"longitude\": 55.792019 }\n    }\n  }\n}"
            }
          ]
        },
        {
          "name": "Fiche + DATAtourisme (I4b · ?format=datatourisme)",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const d = pm.response.json();",
                  "pm.test('bloc data.datatourisme (JSON-LD)', function () { pm.expect(d.data).to.have.property('datatourisme'); pm.expect(d.data.datatourisme['@type']).to.include('PointOfInterest'); });"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [
              {"key": "Accept", "value": "application/json"},
              {"key": "Authorization", "value": "Bearer {{partner_key}}"}
            ],
            "url": {
              "raw": "{{public_base_url}}/api/public/objects/{{object_id}}?format=datatourisme",
              "host": ["{{public_base_url}}"],
              "path": ["api", "public", "objects", "{{object_id}}"],
              "query": [{"key": "format", "value": "datatourisme"}]
            },
            "description": "Ajoute un bloc ADDITIF `data.datatourisme` = document JSON-LD de l'ontologie nationale DATAtourisme (`@type [\"PointOfInterest\", <classe>]`, `rdfs:label`, `hasDescription`, `isLocatedAt`, `hasContact`). Socle cœur — valider contre l'importeur DATAtourisme avant synchro de prod."
          }
        },
        {
          "name": "Fiche + Apidae (I4b · ?format=apidae)",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const d = pm.response.json();",
                  "pm.test('bloc data.apidae', function () { pm.expect(d.data).to.have.property('apidae'); pm.expect(d.data.apidae).to.have.property('type'); });"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [
              {"key": "Accept", "value": "application/json"},
              {"key": "Authorization", "value": "Bearer {{partner_key}}"}
            ],
            "url": {
              "raw": "{{public_base_url}}/api/public/objects/{{object_id}}?format=apidae",
              "host": ["{{public_base_url}}"],
              "path": ["api", "public", "objects", "{{object_id}}"],
              "query": [{"key": "format", "value": "apidae"}]
            },
            "description": "Ajoute un bloc ADDITIF `data.apidae` = objet JSON au format Apidae (`nom.libelleFr`, `type`, `presentation.descriptifCourt`, `localisation.adresse` + `geolocalisation.geoJson`, `informations.moyensCommunication`). Socle cœur — valider contre la plateforme Apidae avant synchro de prod."
          }
        },
        {
          "name": "Fiche + Tourinsoft (I4b · ?format=tourinsoft)",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const d = pm.response.json();",
                  "pm.test('bloc data.tourinsoft', function () { pm.expect(d.data).to.have.property('tourinsoft'); pm.expect(d.data.tourinsoft).to.have.property('SyndObjectID'); });"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [
              {"key": "Accept", "value": "application/json"},
              {"key": "Authorization", "value": "Bearer {{partner_key}}"}
            ],
            "url": {
              "raw": "{{public_base_url}}/api/public/objects/{{object_id}}?format=tourinsoft",
              "host": ["{{public_base_url}}"],
              "path": ["api", "public", "objects", "{{object_id}}"],
              "query": [{"key": "format", "value": "tourinsoft"}]
            },
            "description": "Ajoute un bloc ADDITIF `data.tourinsoft` = enregistrement de syndication SIT (`SyndObjectID`, `type` bordereau, `NomOffre`, `Descriptif`, `Adresse1`/`CodePostal`/`Commune`, `Latitude`/`Longitude`, `Telephone`/`Mel`/`SiteWeb`, `Photo`). Les codes Bertel sont de lignée Tourinsoft. Socle cœur — valider contre le SIT régional avant synchro de prod."
          }
        },
        {
          "name": "Fiche — toutes les langues (C-5 · ?lang=all)",
          "request": {
            "method": "GET",
            "header": [
              {"key": "Accept", "value": "application/json"},
              {"key": "Authorization", "value": "Bearer {{partner_key}}"}
            ],
            "url": {
              "raw": "{{public_base_url}}/api/public/objects/{{object_id}}?lang=all",
              "host": ["{{public_base_url}}"],
              "path": ["api", "public", "objects", "{{object_id}}"],
              "query": [{"key": "lang", "value": "all"}]
            },
            "description": "Ajoute un bloc ADDITIF `data.i18n` = toutes les traductions (texte propre par langue) en un seul appel. Clés de base résolues en FR."
          }
        },
        {
          "name": "Flux tombstone (C-4 · suppressions)",
          "request": {
            "method": "GET",
            "header": [
              {"key": "Accept", "value": "application/json"},
              {"key": "Authorization", "value": "Bearer {{partner_key}}"}
            ],
            "url": {
              "raw": "{{public_base_url}}/api/public/objects/deletions?since=2024-01-01T00:00:00Z",
              "host": ["{{public_base_url}}"],
              "path": ["api", "public", "objects", "deletions"],
              "query": [{"key": "since", "value": "2024-01-01T00:00:00Z"}]
            },
            "description": "Objets DÉFINITIVEMENT supprimés depuis `since` (pour qu'un miroir partenaire retire ses enregistrements fantômes). Projette `{object_id, type, deleted_at}` uniquement. Reprendre la pagination avec `since = meta.cursor`."
          }
        },
        {
          "name": "Catalogues de référentiels (I1)",
          "request": {
            "method": "GET",
            "header": [
              {"key": "Accept", "value": "application/json"},
              {"key": "Authorization", "value": "Bearer {{partner_key}}"}
            ],
            "url": {
              "raw": "{{public_base_url}}/api/public/catalog?domains=amenity,payment_method,language",
              "host": ["{{public_base_url}}"],
              "path": ["api", "public", "catalog"],
              "query": [
                {"key": "domains", "value": "amenity,payment_method,language"},
                {"key": "lang", "value": "fr", "disabled": true}
              ]
            },
            "description": "Vocabulaires contrôlés résolus par langue (forme `{code,name,icon_url,parent_code,domain}`). Sans `domains` → tous les catalogues publics."
          }
        }
      ]
    }
  ],
  "event": [
    {
      "listen": "prerequest",
      "script": {
        "type": "text/javascript",
        "exec": [
          "// Auto-set timestamp for since requests",
          "if (pm.request.url.toString().includes('since_fast')) {",
          "    const timestamp = new Date().toISOString();",
          "    pm.environment.set('current_timestamp', timestamp);",
          "}"
        ]
      }
    },
    {
      "listen": "test",
      "script": {
        "type": "text/javascript",
        "exec": [
          "// Common test for all requests",
          "pm.test('Status code is 200', function () {",
          "    pm.response.to.have.status(200);",
          "});",
          "",
          "pm.test('Response is JSON', function () {",
          "    pm.expect(pm.response.headers.get('Content-Type')).to.include('application/json');",
          "});",
          "",
          "pm.test('Response has required structure', function () {",
          "    const jsonData = pm.response.json();",
          "    ",
          "    if (pm.request.url.toString().includes('get_object_resource')) {",
          "        pm.expect(jsonData).to.have.property('object_id');",
          "        pm.expect(jsonData).to.have.property('type');",
          "        pm.expect(jsonData).to.have.property('status');",
          "    } else if (pm.request.url.toString().includes('list_object_resources')) {",
          "        pm.expect(jsonData).to.have.property('info');",
          "        pm.expect(jsonData).to.have.property('data');",
          "        pm.expect(jsonData.info).to.have.property('kind');",
          "        pm.expect(jsonData.info).to.have.property('language');",
          "    }",
          "});",
          "",
          "// Store useful data for next requests",
          "if (pm.request.url.toString().includes('list_object_resources') && pm.response.json().data.length > 0) {",
          "    const firstObject = pm.response.json().data[0];",
          "    pm.environment.set('object_id', firstObject.object_id);",
          "    if (firstObject.type === 'ITI') {",
          "        pm.environment.set('itinerary_id', firstObject.object_id);",
          "    }",
          "}"
        ]
      }
    }
  ],
  "variable": [
    {
      "key": "base_url",
      "value": "https://api.bertel.example.com",
      "description": "URL de base de l'API Bertel"
    },
    {
      "key": "apikey",
      "value": "your-api-key-here",
      "description": "Votre clé API"
    },
    {
      "key": "authorization",
      "value": "Bearer your-token-here",
      "description": "Token Bearer (alternative à apikey)"
    },
    {
      "key": "public_base_url",
      "value": "https://app.bertel.example.com",
      "description": "URL de l'application (passerelle partenaire /api/public/*)"
    },
    {
      "key": "partner_key",
      "value": "bk_live_your-partner-key-here",
      "description": "Clé partenaire (Bearer) émise par l'OTI pour /api/public/*"
    },
    {
      "key": "object_id",
      "value": "",
      "description": "ID d'objet pour les tests (auto-rempli)"
    },
    {
      "key": "itinerary_id",
      "value": "",
      "description": "ID d'itinéraire pour les tests de tracé (auto-rempli)"
    },
    {
      "key": "current_timestamp",
      "value": "",
      "description": "Timestamp actuel pour les requêtes since (auto-généré)"
    }
  ]
}
