VC Publisher API
Übersicht
Zusätzlich zur Benutzeroberfläche bietet der VC Publisher eine REST API.
Die interaktive API-Dokumentation (Swagger UI) ist unter folgender URL verfügbar:
https://Publisher-url.de/apidoc/v1/#
Die Publisher-url.de muss durch die tatsächliche URL Ihrer VC Publisher-Instanz ersetzt werden.
Alle Endpunkte können direkt im Browser durchsucht und getestet werden.
Bei der Verwendung der Swagger UI klicken Sie auf die Schaltfläche „Try it out" und füllen Sie die erforderlichen Informationen für den jeweiligen Endpunkt aus.
Authentifizierung
Jeder API-Endpunkt außer den Login-Endpunkten erfordert ein gültiges Bearer-Token.
Das Token wird durch den Login-Vorgang erhalten und muss im Authorization-Header jeder nachfolgenden Anfrage enthalten sein:
Authorization: Bearer <your-token>
Ohne ein gültiges Token antwortet die API mit 401 Unauthorized.
Workflow 1: Login & Authentifizierung
Je nach Anwendungsfall gibt es zwei Anmeldemethoden: API-Token-Login für den programmatischen Zugriff und sitzungsbasierter Login für den UI-Zugriff.
API-Token-Login
Schritt 1 – Token abrufen
Senden Sie eine POST-Anfrage an /api/v1/login mit Benutzername und Passwort:
POST /api/v1/login
Content-Type: application/json
{
"username": "ihr-benutzername",
"password": "ihr-passwort"
}
Bei der Verwendung des Login-Endpunkts in der Swagger UI muss "algorithm": "sha-256" entfernt werden, wenn das Passwort im Klartext eingegeben wird.
Eine erfolgreiche Antwort gibt 200 OK zurück:
{
"_id": "64abc...",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6...",
"tokenExpires": "2026-03-12T10:00:00.000Z"
}
Das Feld token ist das Bearer-Token. Das Feld tokenExpires gibt an, wann es ungültig wird.
Schritt 2 – Token verwenden
Fügen Sie das Token in den Authorization-Header jeder Anfrage ein:
GET /api/v1/user/whoami
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6...
Klicken Sie in der Swagger UI auf die Schaltfläche „Authorize" und geben Sie das Token ein, um alle über die Oberfläche gestellten Anfragen zu authentifizieren.
Workflow 2: Projekt erstellen
|
Erfordert die Super-User-Rolle. |
Schritt 1 – Projekt erstellen
Zum Erstellen eines Projekts wird der Endpunkt POST /api/v1/project verwendet. Es müssen ein Name, eine Beschreibung und eine Bounding Box angegeben werden.
POST /api/v1/project
Authorization: Bearer <token>
{
"name": "Mein Beispielprojekt",
"description": "Ein Projekt zur Demonstration der API",
"bbox": [-180, -85, 180, 85]
}
Der optionale Query-Parameter managerId weist einen bestimmten Benutzer als Projektmanager zu. Wird er weggelassen, wird der anfragende Benutzer zum Manager.
Eine erfolgreiche Antwort gibt 201 Created zurück:
{
"_id": "969b26df-ab3...",
"createdAt": "2026-03-11T11:38:45.156Z",
"createdBy": "64abc...",
"updatedAt": "2026-03-11T11:38:45.156Z",
"updatedBy": "64abc...",
"name": "Mein Beispielprojekt",
"description": "Ein Projekt zur Demonstration der API",
"bbox": [
-180,
-85,
180,
85
],
"properties": {
},
"defaultDataBucketId": "816d4486-f5a..."
}
Schritt 2 – Vorhandene Projekte abrufen
Um ein bestimmtes Projekt anhand seiner ID abzurufen, verwenden Sie den Endpunkt GET /api/v1/project/{projectId}.
GET /api/v1/project/\{projectId}
Die Rückgabe sieht genauso aus wie die Antwort in Schritt 1.
Um alle Projekte aufzulisten, auf die der authentifizierte Benutzer Zugriff hat, verwenden Sie den Endpunkt GET /api/v1/projects. Die Anfrage erlaubt verschiedene Query-Parameter zum Filtern und Sortieren der Ergebnisse. Die Parameter limit und page steuern die Paginierung, die Parameter sort und orderBy die Sortierung.
Diese Parameter steuern die Form der Ausgabe und sind Teil der meisten Listenendpunkte.
Die Projektliste unterstützt außerdem spezifische Parameter zum Filtern nach name, description, createdAt, createdBy, updatedAt, updatedBy und bbox.
GET /api/v1/projects
Workflow 3: Benutzer einem Projekt zuweisen
|
Erfordert die MANAGER-Berechtigung für das Projekt. |
Benutzer müssen einem Projekt explizit zugewiesen werden, bevor sie mit ihm interagieren können. Jede Zuweisung verbindet einen Benutzer mit einer Rolle.
Schritt 1 – Benutzer-ID ermitteln
GET /api/v1/users
Der Users-Endpunkt gibt alle Benutzer im System zurück, wenn der Benutzer Administratorrechte hat. Für Benutzer, die nur Projektmanager sind, gibt es den User-Profiles-Endpunkt. Dieser Endpunkt gibt alle Benutzer im System mit eingeschränkten Informationen zurück (ID und Name).
GET /api/v1/user-profiles
Beide Endpunkte bieten eine Filteroption für den username. Der Users-Endpunkt bietet zusätzlich Filter für email, createdAt, createdBy, updatedAt und updatedBy.
Die Rückgabe für Users sieht folgendermaßen aus:
{
"items": [
{
"_id": "v6WEM...",
"createdAt": "2016-02-10T15:46:35.816Z",
"updatedAt": "2025-08-21T07:35:09.841Z",
"updatedBy": "v6WEM...",
"username": "benutzername",
"email": "benutzer@email.de"
},
...
]
}
Die Rückgabe für User-Profiles sieht folgendermaßen aus:
{
"items": [
{
"_id": "v6WEM...",
"username": "benutzername"
},
...
]
}
Beide liefern eine ID, die in Schritt 3 für die Zuweisung eines Benutzers zu einem Projekt benötigt wird.
Schritt 2 – Verfügbare Rollen abrufen
Um einen Benutzer einem Projekt zuzuweisen, muss eine Rolle für den Benutzer angegeben werden. Die verfügbaren Rollen können mit folgendem Endpunkt abgerufen werden:
GET /api/v1/iam/roles
Die Rollen können mit den Standard-Tabellenfiltern und einem Berechtigungsfilter gefiltert werden. Dieser Filter beschreibt die Fähigkeit der Rolle (z. B. getProject).
Die Rolle, die dem Benutzer in einem Projekt zugewiesen werden soll, sollte projektbezogen sein. Der Benutzer in einem Projekt sollte mindestens getProject-Berechtigungen haben. Auf dieser Grundlage werden nur zwei mögliche Rollen zurückgegeben: ProjectMember und ProjectManager. Die Rolle ProjectManager umfasst alle projektbezogenen Berechtigungen, während die Rolle ProjectMember hauptsächlich Leseberechtigungen enthält.
{
"items": [
{
"_id": "84e1b02c-2b...",
"createdAt": "2023-09-06T08:04:23.379Z",
"updatedAt": "2026-01-15T08:08:43.385Z",
"createdBy": "internal",
"updatedBy": "internal",
"name": "projectManager",
"permissions": [
"getProject",
"getDatasource",
"publishDatasource",
"getUser",
"getACL",
"getCredentials",
"createApp",
"createModule",
"editProject",
"createDatasource",
"deleteDatasource",
"editDatasource",
"createDatabase",
"getDatabase",
"deleteDatabase",
"accessDbImport",
"accessDbExport",
"accessDbDelete",
"accessObjectJob",
"accessApplyUpdateJob",
"accessObliqueJob",
"accessPanoramaJob",
"accessPointcloudJob",
"accessSolarJob",
"accessTerrainJob",
"accessTMSJob",
"accessCityDbInfo",
"grantRole",
"revokeRole",
"getJob",
"abortJob",
"createDataBucket",
"getDataBucket",
"editDataBucket",
"uploadToDataBucket",
"deleteDataBucket",
"getApp",
"editApp",
"deleteApp",
"publishApp",
"setAppPublic",
"getModule",
"editModule",
"deleteModule"
]
},
{
"_id": "be48df30-40...",
"createdAt": "2023-09-06T08:04:23.381Z",
"updatedAt": "2023-09-06T08:04:23.381Z",
"createdBy": "internal",
"updatedBy": "internal",
"name": "projectMember",
"permissions": [
"getProject",
"getDatasource",
"publishDatasource",
"getUser",
"getACL",
"getCredentials",
"createScenario",
"createApp",
"createModule"
]
}
],
"limit": 20,
"page": 0,
"totalCount": 2,
"totalPages": 1
}
Schritt 3 – Benutzer zuweisen
Wenn die erforderlichen Voraussetzungen erfüllt sind (userId, projectId und roleId), kann der Benutzer mit folgendem Endpunkt dem Projekt zugewiesen werden.
PUT /api/v1/project/\{projectId}/user/{userId}
Content-Type: application/json
{
"roleId": "<role-id-aus-schritt-2>"
}
Eine erfolgreiche Antwort ist 204 No Content.
Workflow 4: Verarbeitungsauftrag ausführen
Eine Aufgabe (Task) definiert, was verarbeitet werden soll und wann. Ein Job ist die eigentliche Ausführungsinstanz, die beim Ausführen der Aufgabe erstellt wird.
Schritt 1 – Aufgabe erstellen
POST /api/v1/project/\{projectId}/task
{
"labels": [],
"tags": {},
"debugLevel": 2,
"priority": 1,
"name": "Test_api_task",
"description": "task with api settings",
"parameters": {
"datasource": {
"command": "create",
"name": "Vector_Test"
},
"options": {
"input": {
"dataSource": {
"@type": "GeoJSONSource",
"fileSet": [
{
"dir": "C:\\path\\to\\input\\data",
"fileName": [
{
"name": "*.json"
}
]
}
],
"extrudeInfo": {
"extrudePoints": false,
"extrudeLines": false,
"extrudePolygons": false,
"heightPropertyName": "",
"defaultExtrudedHeight": 0
},
"defaultColor": {
"@type": "ColorSymbol",
"value": "#cccccc"
}
},
"heightMode": {
"type": "absolute",
"offset": 0
}
},
"modelOptions": {
"defaultShininess": 0.2,
"defaultCreaseAngle": 10,
"renderPrimitiveOutlines": {
"value": false,
"color": "#000000",
"outlineMode": "Surfaces",
"polygonArray": true
}
},
"tiling": {
"geometricErrorComputationStrategy": {
"@type": "GeometricErrorComputationRelativeToTileSizeStrategy",
"geometricErrorToTileSizeRatio": 0.0115866254
},
"value": {
"@type": "SingleLevelTiling",
"spatialSubdivisionSchema": {
"@type": "QuadtreeSubdivision"
},
"fixedGeneralization": {
"@type": "FixedGeneralization",
"tolerance": 0,
"texelSize": 0
},
"fixedObjectSizeFilter": {
"@type": "FixedObjectSizeFilter",
"thresholdValue": 0
},
"tileLevel": 15
},
"featureSelectionMode": "containsCenter"
},
"processing": {
"convertMaterialsToTextures": false
},
"output": {
"tiles3D_1_1": {
"layerJson": {
"maxLevelsInTileset": 3,
"prettyPrint": true
},
"gltfOptions": {
"exportMetadata": true,
"addSubfeaturesIndicator": true,
"backFaceCulling": true,
"transparencyMode": "combined",
"alphaFilterThreshold": 0.8,
"metallicFactor": 0,
"minFilter": "linear",
"magFilter": "linear",
"prettyPrint": true,
"reverseFeatureIdLabels": true,
"srgbValuesInPbrBaseColorFactor": false,
"usePrimitiveOutlineExtension": true,
"useMaterialsUnlitExtension": false,
"useUnsignedShortIndexAccessors": false,
"imageEncoding": "jpeg_png",
"jpegOptions": {
"jpegCompressionQuality": 0.8,
"jpegChromaSubsampling": "4_2_2"
},
"pngOptions": {
"pngCompressionQuality": 0.5
}
}
}
}
}
},
"properties": {},
"jobType": "vcTilesVector",
"jobVersion": "",
"schedule": {
"type": "immediate"
}
}
Das Feld jobType bestimmt den Typ der Verarbeitung. Das Objekt parameters ist jobtyp-spezifisch.
Das Feld schedule steuert, wann der Job ausgeführt wird:
| Schedule-Wert | Verhalten |
|---|---|
|
Der Job wird ausgeführt, sobald ein Verarbeitungs-Runner verfügbar ist |
|
Der Job wird zu einem bestimmten UTC-Datum und einer bestimmten Uhrzeit ausgeführt |
|
Der Job wiederholt sich nach einem CRON-Zeitplan |
Eine erfolgreiche Antwort gibt 200 OK mit dem erstellten Task-Objekt einschließlich seiner _id zurück.
{
"jobVersion": "",
"priority": 1,
"debugLevel": 2,
"tags": {},
"labels": [],
"properties": {},
"name": "Test_api_task",
"description": "task with api settings",
"jobType": "vcTilesVector",
"schedule": {
"type": "immediate"
},
"projectId": "b68056fc-86ed-4681-...",
"createdAt": "2026-03-12T13:59:38.664Z",
"updatedAt": "2026-03-12T13:59:38.664Z",
"createdBy": "v6WEM2A92...",
"updatedBy": "v6WEM2A92...",
"_id": "07047f43-26ed-4a40-...",
"lastJobId": "954b1c80-7917-4ca0-...",
"parameters": { ... },
}
Workflow 5: Daten hochladen & Datenquelle erstellen
Teil A – Daten in einen Data Bucket hochladen
Ein Data Bucket ist ein Speichercontainer innerhalb eines Projekts. Jedes Projekt hat einen Standard-Data-Bucket, der automatisch zusammen mit dem Projekt erstellt wird.
Schritt 1 – Ziel-Data-Bucket ermitteln
GET /api/v1/project/\{projectId}/data-buckets
Die Antwort enthält eine Liste der Data Buckets im Projekt.
{
"items": [
{
"_id": "57d6913d-af53-4292-...",
"properties": {},
"name": "default-b68056fc-86ed-...",
"createdAt": "2026-01-08T09:15:15.741Z",
"updatedAt": "2026-01-08T09:15:15.741Z",
"createdBy": "v6WEM2A92ozfZaAu5",
"updatedBy": "v6WEM2A92ozfZaAu5",
"projectId": "b68056fc-86ed-4681-..."
}
],
"limit": 20,
"page": 0,
"totalCount": 1,
"totalPages": 1
}
Schritt 2 – Datei hochladen
POST /api/v1/project/\{projectId}/data-bucket/{dataBucketId}/upload
Hängen Sie overwrite=true an, um eine vorhandene Datei mit demselben Namen zu überschreiben. Die Swagger UI bietet ein Datei-Upload-Feld, über das Benutzer zur Datei auf ihrem lokalen Computer navigieren können.
Ein erfolgreicher Einzeldatei-Upload gibt 204 zurück. Beim Hochladen mehrerer Dateien kann die API 207 Multi-Status zurückgeben, wenn nur einige Dateien erfolgreich waren.
Teil B – Datenquelle erstellen
Eine Datenquelle ist eine registrierte Referenz auf Daten, die in einem Data Bucket oder unter einer externen URL gespeichert sind.
Es gibt zwei Quelltypen: internal (Data Bucket) und external (URL).
Interne Datenquelle:
POST /api/v1/project/\{projectId}/datasource
{
"name": "Name der Datenquelle",
"type": "geojson",
"typeProperties": {
"screenSpaceError": 16
},
"sourceProperties": {
"type": "internal",
"dataBucketId": "{dataBucketId}",
"dataBucketKey": "pfad/zur/hochgeladenen/datei.json"
}
}
Externe Datenquelle:
POST /api/v1/project/\{projectId}/datasource
{
"name": "Name der Datenquelle",
"type": "wms",
"typeProperties": {
"layers": ["layer_name"],
"version": "1.3.0",
"format": "image/png"
},
"sourceProperties": {
"type": "external",
"url": "https://example.com/wms"
}
}
Die folgenden type-Werte werden unterstützt:
| Typ | Beschreibung |
|---|---|
|
3D-Kachelset (z. B. Cesium 3D Tiles) |
|
GeoJSON-Vektordaten |
|
Schrägluftbilder |
|
Quantized-Mesh-Gelände |
|
Geländenetz im Netz |
|
Web Map Service |
|
Web Map Tile Service |
|
Tile Map Service |
|
Cloud Optimized GeoTIFF |
|
FlatGeobuf-Vektordaten |
|
I3S Scene Layer |
|
Vektorkacheln |
|
Generischer / benutzerdefinierter Typ |
|
Panoramabilder |
Eine erfolgreiche Antwort gibt 201 Created zurück:
{
"_id": "ds-id-xyz...",
"name": "Name der Datenquelle",
"type": "geojson",
"uri": "https://publisher-url.de/data/...",
"projectId": "proj-id-abc123",
"jobIds": [],
"publishTaskIds": [],
"dataUpdatedAt": "2026-03-11T09:30:00.000Z",
"dataUpdatedBy": "user-id"
}
Workflow 6: App mit Modulen erstellen
Schritt 1 – App erstellen
Um eine App zu erstellen, senden Sie eine POST-Anfrage an /api/v1/project/{projectId}/app mit dem App-Namen, einer Beschreibung und einem Array von Modul-IDs.
Das Feld mapVersion gibt die VC Map Viewer Engine-Version als Semver-Bereich an.
Zusätzlich kann eine MemberId als Query-String hinzugefügt werden. Wenn keine MemberId angegeben wird, wird die App mit den Berechtigungen des anfragenden Benutzers erstellt. Wenn eine MemberId angegeben wird, wird die App mit den Berechtigungen dieses Benutzers erstellt. Die MemberId muss dem Projekt bereits zugewiesen sein.
POST /api/v1/project/\{projectId}/app
{
"name": "Meine Stadt-App",
"description": "Öffentlich zugängliche 3D-Stadt-App",
"mapVersion": "^6.0.0",
"moduleIds": ["module-id-abc"]
}
Wenn mehrere Module in moduleIds aufgeführt sind, werden deren Layer und Viewpoints sequenziell zusammengeführt. Die Erstellung eines Moduls wird im nächsten Schritt beschrieben, aber Module können auch unabhängig erstellt und später zur App hinzugefügt werden.
Eine erfolgreiche Antwort gibt 201 Created zurück:
{
"_id": "app-id-xyz",
"name": "Meine Stadt-App",
"projectId": "proj-id-abc123",
"moduleIds": ["module-id-abc"],
"mapVersion": "^6.0.0",
"publishTaskIds": [],
"isPublic": false,
"createdAt": "2026-03-13T10:47:45.931Z",
"updatedAt": "2026-03-13T10:47:45.931Z",
"createdBy": "v6WEM2A92ozfZaAu5",
"updatedBy": "v6WEM2A92ozfZaAu5"
}
Speichern Sie die _id als {appId}. Die App ist erst öffentlich zugänglich, nachdem sie in Schritt 6 veröffentlicht wurde.
Schritt 2 – Modul erstellen
POST /api/v1/project/\{projectId}/module
{
"name":"Mein Basismodul",
"description":"Beschreibung meines Basismoduls",
"properties":{
},
"layers":[
{
"type":"OpenStreetMapLayer",
"name":"OpenStreetMapLayer(1)",
"properties":{
"attributions":{
"provider":"OpenStreetMap contributors",
"url":"http://www.openstreetmap.org/",
"year":"2026"
}
},
"activeOnStartup":true,
"zIndex":0
},
{
"type":"GeoJSONLayer",
"name":"test_api_datasource",
"activeOnStartup":true,
"url":"./datasource-data/f4a59d97-4401-45ab-b31a-2e5ad6569fc9/testLake3_withZ.json",
"extent":{
"coordinates":[
12.278030916360558,
53.76142514632812,
12.32886225819537,
53.778920631506764
],
"projection":{
"type":"Projection",
"epsg":"EPSG:4326"
},
"type":"Extent"
},
"datasourceId":"f4a59d97-4401-45ab-b31a-2e5ad6569fc9",
"zIndex":0
}
],
"maps":[
{
"type":"CesiumMap",
"name":"CesiumMap"
}
],
"contentTree":[
{
"type":"LayerContentTreeItem",
"name":"OpenStreetMapLayer(1)",
"layerName":"OpenStreetMapLayer(1)"
}
],
"startingMapName":"CesiumMap",
}
Die Layer im Modul können auf Datenquellen referenzieren, die in Workflow 5 erstellt wurden.
Eine erfolgreiche Antwort gibt 201 Created zurück:
{
"_id": "module-id-abc",
"name": "Mein Basismodul",
"projectId": "proj-id-abc123",
"layers": [ ... ],
"viewpoints": [ ... ],
"createdAt": "2026-03-11T09:45:00.000Z"
}
Schritt 3 – Module hinzufügen
Dies ersetzt das bestehende moduleIds-Array vollständig – fügen Sie alle Module ein, nicht nur die neuen:
Es müssen nur die Felder in den Anfrage-Body aufgenommen werden, die überschrieben werden sollen.
PUT /api/v1/project/\{projectId}/app/\{appId}
{
"moduleIds": ["module-id-abc", "module-id-second"]
}