Dieser Leitfaden zur SAP Gemini API ABAP Integration erklärt Schritt für Schritt, wie SAP (ABAP) sicher mit der Google Gemini API (Generative Language API) kommuniziert.
Außerdem zeigen wir, wie du dabei von Zertifikaten in STRUST über die RFC-Destination in SM59 bis hin zum produktiven HTTP-POST in ABAP vorgehst. Weitere Tipps findest du außerdem in unserem Beitrag Was ist SAP?.
Inhaltsverzeichnis
- Warum eine SAP Gemini API ABAP Integration?
- Schritt 1: SM59 – HTTP-Destination für Google-APIs anlegen
- Schritt 2: STRUST – Zertifikate für den HTTPS-Zugriff auf Google-APIs
- Schritt 3: SAP Gemini API ABAP Integration – POST-Request an Gemini (Minimalbeispiel)
- Best Practices für die SAP Gemini API ABAP Integration

Warum eine SAP Gemini API ABAP Integration?
- Textanalyse, Zusammenfassungen, Klassifikation sowie zudem Prompt-basierte Automatisierung direkt aus ABAP.
- Außerdem erfolgt die Anbindung einfach über einen API-Key sowie zudem über eine standardisierte REST-Schnittstelle.
- Dadurch ist die Lösung skalierbar vom Testbetrieb bis hin zur produktiven Nutzung.
Voraussetzungen
- Zunächst benötigst du ein SAP-System mit aktivem HTTPS (ICM) sowie zudem CommonCryptoLib.
- Außerdem brauchst du Berechtigungen für STRUST sowie für SM59.
- Zudem ist ein gültiger Gemini API-Key notwendig.
- Außerdem benötigst du eine ABAP-JSON-Utility, beispielsweise
/UI2/CL_JSON.
Schritt 1: SM59 – HTTP-Destination für Google-APIs anlegen
Damit die SAP Gemini API ABAP Integration funktioniert, legst du zunächst in SM59 eine HTTP-Destination an, über die SAP externe Webservices oder APIs anspricht.
Für generativelanguage.googleapis.com sieht die Grundkonfiguration daher so aus:
Neue HTTP-Verbindung anlegen
- Klicke anschließend auf Anlegen.
- Wähle danach den Verbindungstyp G – HTTP-Verbindung zu externem Server.
- Vergib anschließend einen sprechenden Namen (z. B.
GOOGLE_GENAI_APIoderGOOGLE_GEMINI_API).
Technische Einstellungen
- Host:
generativelanguage.googleapis.com - Service-Nr.:
443, denn HTTPS nutzt diesen Port - Pfad-Präfix: zunächst leer lassen – der vollständige Pfad wird im ABAP-Code gesetzt
(z. B./v1/models/gemini-2.5-flash:generateContent).
Logon & Security
- SNC: nicht erforderlich, weil HTTPS verwendet wird.
- SSL: Aktiv (SSL-Client Standard) wählen
(oder eure dedizierte SSL-Client-Identität, sofern in STRUST hinterlegt).
Anmeldung & Sicherheit
Für Google-APIs werden in der Destination normalerweise keine Benutzer-/Passwortdaten gepflegt. Stattdessen erfolgt die Authentifizierung im ABAP-Code – entweder per API-Key im Header oder alternativ über OAuth-2.0-Tokens (Header
Authorization: Bearer ).
- Benutzer/Passwort: bleibt leer, denn die Authentifizierung erfolgt im Code.
- SSL-Client-Zertifikat: entspricht der Auswahl unter Technische Einstellungen.
Bei mehreren Identitäten ggf. gezielt auswählen.
Spezielle Optionen
- HTTP-Proxy: nur dann pflegen, falls der Internetzugang darüber läuft.
- Timeouts: nach Bedarf anpassen, damit langsame Antworten abgefangen werden.
Zusammenfassung
- Host:
generativelanguage.googleapis.com - Service:
443 - Pfad-Präfix: leer (Pfad wird im Code gesetzt)
- SSL: aktiv, SSL-Client Standard
- Anmeldung: leer (Auth im ABAP-Code)
Schritt 2: STRUST – Zertifikate für den HTTPS-Zugriff auf Google-APIs
In STRUST pflegst du anschließend die SSL/TLS-Vertrauensanker, damit dein SAP-System die von Google präsentierten Serverzertifikate akzeptiert.
Wo eintragen?
Wechsle zunächst in STRUST zum Knoten SSL client (Standard) oder alternativ zu eurer spezifischen SSL-Client-Identität. Anschließend siehst du rechts in der
Zertifikatsliste alle bereits vertrauten Zertifikate. Hier müssen daher die Root- und – sofern vorhanden –
auch die Intermediate-Zertifikate der ausstellenden CA von Google liegen.
Welche Zertifikate werden benötigt?
Google nutzt in der Regel Ketten von bekannten CAs wie Google Trust Services (GTS), GlobalSign oder DigiCert. In vielen Systemen sind die wichtigen Root-Zertifikate bereits vorhanden, weil Betriebssystem oder CCL diese oft mitliefern. Falls jedoch etwas fehlt, ergänze die Kette manuell.
Zertifikate ermitteln und exportieren
https://generativelanguage.googleapis.comim Browser öffnen.- Auf das Schloss-Symbol klicken und die Zertifikatskette anzeigen.
- Root- und ggf. Intermediate-Zertifikate (z. B. GTS Root R1, GTS CA 1O1) im Format Base64-X.509
(.ceroder.pem) speichern. Alternativ von den offiziellen Seiten der Google Trust Services laden.
Import in STRUST
- STRUST öffnen und SSL client (Standard) auswählen.
- Nutze anschließend die Schaltfläche Importzertifikat und wähle danach die gespeicherten Dateien aus.
- Füge danach die Zertifikate der Liste hinzu und sichere anschließend die Datenbank, sodass die Änderungen aktiv werden.
- Nach dem Import sollten die Einträge sichtbar sein, weil andernfalls der Import fehlschlug.
Verbindung prüfen
Führe anschließend in SM59 bei deiner Destination einen Verbindung testen aus. Falls der Test fehlschlägt, fehlt häufig ein
Root- oder Intermediate-Zertifikat. Beachte jedoch: Dieser Test prüft nur Netzwerk und TLS-Handshake, während die spätere
Authentifizierung per API-Key oder OAuth nicht abgedeckt wird.
Zusammenfassung
- Ort: SSL client (Standard) (oder die verwendete SSL-Client-PSE).
- Als Inhalt dienen außerdem vertrauenswürdige Root- bzw. Intermediate-Zertifikate der Google-CAs (z. B. GTS Root R1, GTS CA 1O1).
- Als Aktion solltest du zunächst das Vorhandensein prüfen und anschließend fehlende Zertifikate importieren und speichern.
Nächster Schritt in ABAP
Sobald die Vorarbeiten abgeschlossen sind, erfolgt die eigentliche API-Kommunikation (HTTP-Methode, Header, Body, Authentifizierung) anschließend im Code,
beispielsweise mit CL_HTTP_CLIENT oder alternativ CL_REST_HTTP_CLIENT.
Schritt 3: SAP Gemini API ABAP Integration – POST-Request an Gemini (Minimalbeispiel)
Beispielendpunkt (v1, Modell gemini-2.5-flash): /v1/models/gemini-2.5-flash:generateContent
REPORT z_ki_google_test.
DATA: lo_http TYPE REF TO if_http_client,
lv_body TYPE string,
lv_result TYPE string,
lv_api_key TYPE string VALUE '***PLACE_YOUR_API_KEY_SECURELY***'.
" 1) HTTP-Client aus SM59-Destination (G: HTTP)
cl_http_client=>create_by_destination(
EXPORTING destination = 'GEMINI'
IMPORTING client = lo_http ).
" 2) Header setzen
lo_http->request->set_method( if_http_request=>co_request_method_post ).
lo_http->request->set_header_field( name = 'Content-Type' value = 'application/json' ).
lo_http->request->set_header_field( name = 'x-goog-api-key' value = lv_api_key ).
" 3) Request-Pfad (Endpoint) – setze ihn NUR hier ODER als Präfix in SM59 (nicht beides!)
lo_http->request->set_header_field(
name = '~request_uri'
value = '/v1/models/gemini-2.5-flash:generateContent' ).
" ---------- Request-JSON aufbauen (mit name_mappings für lowercase keys) ----------
TYPES: BEGIN OF ty_part_req,
text TYPE string,
END OF ty_part_req.
TYPES: ty_t_part_req TYPE STANDARD TABLE OF ty_part_req WITH EMPTY KEY.
TYPES: BEGIN OF ty_content_req,
parts TYPE ty_t_part_req,
END OF ty_content_req.
TYPES: ty_t_content_req TYPE STANDARD TABLE OF ty_content_req WITH EMPTY KEY.
TYPES: BEGIN OF ty_request,
contents TYPE ty_t_content_req,
END OF ty_request.
DATA ls_req TYPE ty_request.
DATA(lv_prompt_text) = |Erkläre KI in einem Satz.|.
APPEND VALUE ty_content_req(
parts = VALUE #( ( text = lv_prompt_text ) ) )
TO ls_req-contents.
DATA lt_req_map TYPE /ui2/cl_json=>name_mappings.
DATA lt_res_map TYPE /ui2/cl_json=>name_mappings.
" Request-Mapping (ABAP-Feldname -> JSON-Key, lowercase)
INSERT VALUE /ui2/cl_json=>name_mapping( abap = 'CONTENTS' json = 'contents' ) INTO TABLE lt_req_map.
INSERT VALUE /ui2/cl_json=>name_mapping( abap = 'PARTS' json = 'parts' ) INTO TABLE lt_req_map.
INSERT VALUE /ui2/cl_json=>name_mapping( abap = 'TEXT' json = 'text' ) INTO TABLE lt_req_map.
" Response-Mapping
INSERT VALUE /ui2/cl_json=>name_mapping( abap = 'CANDIDATES' json = 'candidates' ) INTO TABLE lt_res_map.
INSERT VALUE /ui2/cl_json=>name_mapping( abap = 'CONTENT' json = 'content' ) INTO TABLE lt_res_map.
INSERT VALUE /ui2/cl_json=>name_mapping( abap = 'PARTS' json = 'parts' ) INTO TABLE lt_res_map.
INSERT VALUE /ui2/cl_json=>name_mapping( abap = 'TEXT' json = 'text' ) INTO TABLE lt_res_map.
lv_body = /ui2/cl_json=>serialize(
data = ls_req
name_mappings = lt_req_map
compress = abap_true ).
" 4) Senden & Empfangen
lo_http->request->set_cdata( lv_body ).
lo_http->send( ).
lo_http->receive( ).
" 5) Antwort lesen (Status + Body)
DATA: lv_status TYPE i,
lv_reason TYPE string.
lo_http->response->get_status(
IMPORTING
code = lv_status
reason = lv_reason ).
lv_result = lo_http->response->get_cdata( ).
" ---------- Response-JSON deserialisieren ----------
TYPES: BEGIN OF ty_part_res,
text TYPE string,
END OF ty_part_res.
TYPES: ty_t_part_res TYPE STANDARD TABLE OF ty_part_res WITH EMPTY KEY.
TYPES: BEGIN OF ty_content_res,
parts TYPE ty_t_part_res,
END OF ty_content_res.
TYPES: BEGIN OF ty_candidate,
content TYPE ty_content_res,
END OF ty_candidate.
TYPES: ty_t_candidate TYPE STANDARD TABLE OF ty_candidate WITH EMPTY KEY.
TYPES: BEGIN OF ty_response,
candidates TYPE ty_t_candidate,
END OF ty_response.
DATA ls_resp TYPE ty_response.
TRY.
/ui2/cl_json=>deserialize(
EXPORTING json = lv_result
name_mappings = lt_res_map
CHANGING data = ls_resp ).
DATA(lv_text) = ||.
IF lines( ls_resp-candidates ) > 0
AND lines( ls_resp-candidates[ 1 ]-content-parts ) > 0.
lv_text = ls_resp-candidates[ 1 ]-content-parts[ 1 ]-text.
ENDIF.
"=== ALV-Vorbereitung ======================================================
TYPES: BEGIN OF ty_company_info,
field TYPE string,
value TYPE string,
END OF ty_company_info.
DATA: lt_company_info TYPE STANDARD TABLE OF ty_company_info,
ls_company_info TYPE ty_company_info.
IF lv_status = 200 AND lv_text IS NOT INITIAL.
" Antwort in Zeilen aufteilen und Feld: Wert extrahieren
DATA(lt_lines) = VALUE stringtab( ).
SPLIT lv_text AT cl_abap_char_utilities=>newline INTO TABLE lt_lines.
LOOP AT lt_lines INTO DATA(lv_line).
IF lv_line CS ':'.
SPLIT lv_line AT ':' INTO ls_company_info-field ls_company_info-value.
CONDENSE ls_company_info-field.
SHIFT ls_company_info-value LEFT DELETING LEADING space.
ELSE.
ls_company_info-field = 'Text'.
ls_company_info-value = lv_line.
ENDIF.
APPEND ls_company_info TO lt_company_info.
CLEAR ls_company_info.
ENDLOOP.
ELSE.
" Fehlerfall als ALV zeigen
ls_company_info-field = |HTTP|.
ls_company_info-value = |{ lv_status } { lv_reason }|.
APPEND ls_company_info TO lt_company_info.
CLEAR ls_company_info.
ls_company_info-field = |Fehlermeldung|.
ls_company_info-value = lv_result.
APPEND ls_company_info TO lt_company_info.
ENDIF.
"=== ALV-Ausgabe ===========================================================
DATA: lo_alv TYPE REF TO cl_salv_table,
lo_columns TYPE REF TO cl_salv_columns_table,
lo_column TYPE REF TO cl_salv_column_table.
cl_salv_table=>factory(
IMPORTING r_salv_table = lo_alv
CHANGING t_table = lt_company_info ).
lo_columns = lo_alv->get_columns( ).
lo_columns->set_optimize( abap_true ).
lo_column ?= lo_columns->get_column( 'FIELD' ).
lo_column->set_short_text( 'Kategorie' ).
lo_column->set_medium_text( 'Kategorie' ).
lo_column->set_long_text( 'Informationskategorie' ).
lo_column ?= lo_columns->get_column( 'VALUE' ).
lo_column->set_short_text( 'Inhalt' ).
lo_column->set_medium_text( 'Beschreibung' ).
lo_column->set_long_text( 'Detail' ).
lo_alv->display( ).
CATCH cx_root INTO DATA(lx).
" Fallback: Fehler in einfacher Liste ausgeben
WRITE: / 'JSON-/ALV-Fehler:', lx->get_text( ).
WRITE: / 'Raw-Response:', / lv_result.
ENDTRY.
lo_http->close( ).
Best Practices für die SAP Gemini API ABAP Integration
- API-Key nicht hartkodieren, sondern sicher ablegen (Secure Store, Variablen, SICF-Handler).
- Außerdem solltest du Timeouts und Retries einbauen, damit Fehlerzustände klar geloggt werden.
- Halte zudem Prompts kurz und eindeutig, damit die Antworten konsistent bleiben.
- Modellwahl:
gemini-2.5-flashfür Kosten/Speed,gemini-2.5-profür Qualität.
Troubleshooting
- 401 Unauthorized: Hier fehlt entweder
x-goog-api-keyoder er ist falsch. - 400 Bad Request: JSON-Struktur prüfen (
contents → parts → text). - 404 Not Found: Daher solltest du Modellname und URI prüfen.
- SSL-Handshake-Fehler treten auf, weil die CA-Kette in STRUST unvollständig ist.
- Proxy/Firewall: Daher solltest du sowohl SM59-Proxy als auch Netzwerkfreigaben prüfen.
Checkliste
- CA-Kette in STRUST importiert, sodass TLS funktioniert
- Zudem ist in SM59 Host, Port 443 sowie SSL aktiv
- API-Key sicher hinterlegt, sodass auch der Header korrekt gesetzt ist
- Außerdem ist der Endpoint korrekt:
/v1/models/gemini-2.5-flash:generateContent - Außerdem sind Timeouts, Retries und Logging vorhanden
Mit dieser Checkliste schließt du die SAP Gemini API ABAP Integration ab. Außerdem stellst du dadurch sicher, dass dein System zuverlässig funktioniert.




