v1Stabil · HTTPS · JSON

geembee REST API

Integriere Standortdaten direkt in deine Anwendung. Die aktuelle v1 deckt Standorte, Öffnungszeiten, Reviews, Menüs, den öffentlichen geembee Blog und einen einfachen Sync-Trigger für Partner-Workflows ab.

Basis-URL

https://geembee.com/api/v1

Alle Anfragen werden über HTTPS verarbeitet. HTTP-Anfragen werden automatisch auf HTTPS umgeleitet.

Authentifizierung

Jede Anfrage muss zwei Header enthalten:

HeaderBeschreibung
X-GeemBee-KeyÖffentlicher API Key (beginnt mit gbk_live_)
X-GeemBee-SecretAPI Secret (wurde beim Erstellen des Keys einmalig angezeigt)
curl https://geembee.com/api/v1/locations \
  -H "X-GeemBee-Key: gbk_live_deinKey" \
  -H "X-GeemBee-Secret: deinSecret"

Optionale Request-Signierung (empfohlen)

Für erhöhte Sicherheit kannst du Anfragen mit HMAC-SHA256 signieren. Damit wird Replay-Attacken vorgebeugt (±5 Minuten Zeitfenster). Für Blog-Schreibendpunkte ist diese Signierung verpflichtend.

# Signierung: HMAC-SHA256(secret, "{timestamp}.{body}")
X-GeemBee-Timestamp: 1740000000
X-GeemBee-Signature: hmac_sha256(secret, "1740000000.{requestBody}")

Berechtigungen (Scopes)

Jeder API Key hat definierte Berechtigungen. Beim Anfordern eines Keys gibst du an, welche Scopes du benötigst.

ScopeBeschreibung
LOCATIONS_READStandortdaten, Öffnungszeiten und Details lesen
REVIEWS_READGoogle Reviews für deine Standorte abrufen
SYNC_TRIGGERDatensync mit Google Business Profile auslösen
WEBHOOKS_MANAGEWebhook-URL im Partner-Key hinterlegen (aktuell Admin-/Partner-Setup)
BLOG_WRITEBlogbeiträge und Blogbilder auf geembee.com erstellen und verwalten

Endpunkte

Hinweis: Die meisten Endpunkte arbeiten mit der Google `placeId`. Der Menü-Endpunkt verwendet aktuell die interne geembee-`locationId`.

GET/api/v1/locationsScope: LOCATIONS_READ

Gibt alle aktiven Standorte des API Key-Inhabers zurück.

Beispiel-Antwort

{
  "success": true,
  "data": [
    {
      "id": "clx1234...",
      "name": "Mein Unternehmen GmbH",
      "address": "Mariahilfer Straße 1, 1060 Wien",
      "phone": "+43 1 234567",
      "website": "https://example.at",
      "category": "Restaurant",
      "placeId": "ChIJN1t_tDeuEmsRUsoyG83frY4",
      "gmbLocationId": "locations/12345678901234567",
      "lastSyncedAt": "2026-02-27T10:00:00Z"
    }
  ],
  "meta": { "total": 1, "apiVersion": "v1" }
}
GET/api/v1/locations/:placeIdScope: LOCATIONS_READ

Gibt Details zu einem einzelnen Standort anhand der Google Place ID zurück.

Parameter

NameTypPflichtBeschreibung
placeIdstringGoogle Place ID (ChIJ...)

Beispiel-Antwort

{
  "success": true,
  "data": {
    "id": "clx1234...",
    "name": "Mein Unternehmen GmbH",
    "address": "Mariahilfer Straße 1, 1060 Wien",
    "phone": "+43 1 234567",
    "website": "https://example.at",
    "placeId": "ChIJN1t_tDeuEmsRUsoyG83frY4",
    "lastSyncedAt": "2026-02-27T10:00:00Z",
    "openingHours": {
      "monday": { "open": "09:00", "close": "18:00" },
      "tuesday": { "open": "09:00", "close": "18:00" }
    }
  }
}
GET/api/v1/locations/:placeId/hoursScope: LOCATIONS_READ

Gibt die Öffnungszeiten eines Standorts zurück.

Parameter

NameTypPflichtBeschreibung
placeIdstringGoogle Place ID

Beispiel-Antwort

{
  "success": true,
  "data": {
    "monday":    { "open": "09:00", "close": "18:00" },
    "tuesday":   { "open": "09:00", "close": "18:00" },
    "wednesday": { "open": "09:00", "close": "18:00" },
    "thursday":  { "open": "09:00", "close": "18:00" },
    "friday":    { "open": "09:00", "close": "17:00" },
    "saturday":  { "open": "10:00", "close": "14:00" },
    "sunday":    null
  }
}
GET/api/v1/locations/:placeId/reviewsScope: REVIEWS_READ

Gibt Google Reviews für einen Standort zurück (paginiert).

Parameter

NameTypPflichtBeschreibung
placeIdstringGoogle Place ID
limitnumberAnzahl pro Seite (max. 100, default: 20)
cursorstringCursor für Paginierung

Beispiel-Antwort

{
  "success": true,
  "data": [
    {
      "id": "rev_abc123",
      "reviewer": "Max Mustermann",
      "rating": 5,
      "comment": "Sehr guter Service!",
      "reply": null,
      "repliedAt": null,
      "publishedAt": "2026-02-01T14:30:00Z",
      "updatedAt": "2026-02-01T14:30:00Z"
    }
  ],
  "meta": {
    "limit": 20,
    "nextCursor": "rev_xyz456"
  }
}
GET/api/v1/menus/:locationIdScope: LOCATIONS_READ

Gibt die aktiven Menüs einer geembee-Location inklusive Sektionen und verfügbarer Einträge zurück.

Parameter

NameTypPflichtBeschreibung
locationIdstringInterne geembee Location-ID (nicht die Google Place ID)

Beispiel-Antwort

{
  "success": true,
  "data": [
    {
      "id": "menu_123",
      "name": "Frühstück",
      "isActive": true,
      "sortOrder": 0,
      "sections": [
        {
          "id": "section_abc",
          "name": "Getränke",
          "sortOrder": 0,
          "items": [
            {
              "id": "item_xyz",
              "name": "Cappuccino",
              "description": "Mit Hafermilch erhältlich",
              "price": 4.2,
              "priceText": null,
              "isAvailable": true
            }
          ]
        }
      ]
    }
  ],
  "meta": {
    "locationId": "clx1234...",
    "totalMenus": 1,
    "apiVersion": "v1"
  }
}
POST/api/v1/locations/syncScope: SYNC_TRIGGER

Bestätigt einen Sync-Trigger für einen Standort. Die aktuelle v1-Antwort aktualisiert `syncedAt` und liefert den Trigger-Status zurück.

Parameter

NameTypPflichtBeschreibung
placeIdstringGoogle Place ID des zu synchronisierenden Standorts

Beispiel-Antwort

{
  "success": true,
  "data": {
    "locationId": "clx1234...",
    "placeId": "ChIJN1t_tDeuEmsRUsoyG83frY4",
    "syncedAt": "2026-02-27T10:15:00Z",
    "status": "synced"
  }
}
POST/api/v1/blog/mediaScope: BLOG_WRITE

Lädt ein KI-generiertes Blogbild als Base64/Data-URL in den geembee Storage hoch. HMAC-Signatur ist verpflichtend.

Parameter

NameTypPflichtBeschreibung
imagestringBase64 oder data:image/png;base64,... (PNG, JPEG oder WebP, max. 10 MB)
filenamestringDateiname, z.B. kmu-ki-google-business.png
contentTypestringimage/png, image/jpeg oder image/webp
altstringAlt-Text für das Bild

Beispiel-Antwort

{
  "success": true,
  "file": {
    "id": "clxmedia...",
    "filename": "kmu-ki-google-business.png",
    "url": "https://bucket.s3.eu-central-1.amazonaws.com/blog/...",
    "key": "blog/user/...",
    "contentType": "image/png",
    "alt": "Unternehmerin plant KI-gestützte Google-Beiträge"
  }
}
POST/api/v1/blog/postsScope: BLOG_WRITE

Erstellt einen Blogbeitrag für den öffentlichen geembee Blog. HMAC-Signatur ist verpflichtend; der Content wird sicher als Markdown-light/Text gerendert.

Parameter

NameTypPflichtBeschreibung
titlestringTitel des Blogbeitrags
contentstringArtikeltext mit Absätzen, ##/### Überschriften und Listen
statusstringDRAFT, PUBLISHED oder ARCHIVED; Default: DRAFT
coverImageUrlurlURL des Blogbilds, z.B. aus /api/v1/blog/media
seoTitlestringSEO-Titel
seoDescriptionstringMeta-Description

Beispiel-Antwort

{
  "success": true,
  "data": {
    "id": "clxpost...",
    "title": "KI für KMU: Google Business Profile effizienter nutzen",
    "slug": "ki-fuer-kmu-google-business-profile-effizienter-nutzen",
    "status": "PUBLISHED",
    "publishedAt": "2026-05-19T08:15:00.000Z",
    "coverImageUrl": "https://bucket.s3.eu-central-1.amazonaws.com/blog/...",
    "url": "https://www.geembee.com/blog/ki-fuer-kmu-google-business-profile-effizienter-nutzen"
  }
}

Fehlercodes

HTTP StatusBedeutung
200Erfolgreich
400Ungültige Anfrage (fehlende oder falsche Parameter)
401Authentifizierung fehlgeschlagen (falscher Key/Secret)
403Fehlender Scope für diese Aktion
404Ressource nicht gefunden
429Rate Limit überschritten
500Interner Serverfehler

Fehler-Antwort Format

{ "error": "Beschreibung des Fehlers" }

Rate Limiting

Standardmäßig sind 60 Anfragen pro Minute erlaubt. Bei Überschreitung wird HTTP 429 zurückgegeben. Für höhere Limits kontaktiere uns.

Code-Beispiele

JavaScript / TypeScript

const response = await fetch(
  "https://geembee.com/api/v1/locations",
  {
    headers: {
      "X-GeemBee-Key": process.env.GEEMBEE_API_KEY,
      "X-GeemBee-Secret": process.env.GEEMBEE_API_SECRET,
    },
  }
);

const { data } = await response.json();
console.log(data); // Array of locations

Signierter Blog-Post

import crypto from "node:crypto";

const body = JSON.stringify({
  title: "KI für KMU: Google Business Profile effizienter nutzen",
  content: "## Warum lokale Sichtbarkeit zählt\n\n...",
  status: "PUBLISHED",
  tags: ["KI", "KMU", "Google Business Profile"],
});

const timestamp = Math.floor(Date.now() / 1000).toString();
const signature = crypto
  .createHmac("sha256", process.env.GEEMBEE_API_SECRET!)
  .update(`${timestamp}.${body}`)
  .digest("hex");

await fetch("https://geembee.com/api/v1/blog/posts", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-GeemBee-Key": process.env.GEEMBEE_API_KEY!,
    "X-GeemBee-Secret": process.env.GEEMBEE_API_SECRET!,
    "X-GeemBee-Timestamp": timestamp,
    "X-GeemBee-Signature": signature,
  },
  body,
});

PHP

$response = file_get_contents(
  "https://geembee.com/api/v1/locations",
  false,
  stream_context_create([
    "http" => [
      "header" => implode("\r\n", [
        "X-GeemBee-Key: " . getenv("GEEMBEE_API_KEY"),
        "X-GeemBee-Secret: " . getenv("GEEMBEE_API_SECRET"),
      ]),
    ],
  ])
);
$data = json_decode($response, true);

API Key anfragen

Die geembee API ist für externe Partner verfügbar. Kontaktiere uns für einen API Key.

[email protected]
API Dokumentation – geembee | geembee