[{"data":1,"prerenderedAt":757},["ShallowReactive",2],{"navbar-en":3,"footer-en":25,"company-en":71,"blog-post-en-otobo-openticketai-connector":158},{"id":4,"extension":5,"items":6,"meta":22,"stem":23,"__hash__":24},"navbar_en/en/_data/navbar.yml","yml",[7,10,13,16,19],{"label":8,"to":9},"Home","/",{"label":11,"to":12},"Services","/services",{"label":14,"to":15},"Blog","/blogs",{"label":17,"to":18},"Booking","/booking",{"label":20,"to":21},"Contact","/contact",{},"en/_data/navbar","0s4EZWfFOzJefxw_XvqUtNphYWEmsyUdeXrL4zEnryI",{"id":26,"columns":27,"extension":5,"meta":68,"stem":69,"__hash__":70},"footer_en/en/_data/footer.yml",[28,38,54],{"title":29,"links":30},"Company",[31,32,35],{"label":20,"to":21},{"label":33,"to":34},"Impressum","/contact/impressum",{"label":36,"to":37},"Data Privacy","/contact/dataprivacy",{"title":11,"links":39},[40,43,46,49,52],{"label":41,"to":42},"Ticket Systems (OTOBO & Znuny)","/service-groups/ticket-systems",{"label":44,"to":45},"AI Services","/services#ai-services",{"label":47,"to":48},"Support & Hosting","/service-groups/support",{"label":50,"to":51},"Engineering Days","/service-groups/flexible",{"label":53,"to":12},"All Services",{"title":55,"links":56},"Resources",[57,59,62,65],{"label":14,"to":58},"/blog",{"label":60,"to":61},"OTOBO Docs","https://otobo-docs.softoft.de",{"label":63,"to":64},"Znuny Docs","https://znuny-docs.softoft.de/en/",{"label":66,"to":67},"OpenITSMHub","https://openitsmhub.com",{},"en/_data/footer","EOGiSGXXzb1NDA1NJvk2483aI4KLPCglbynPMxJZ-gM",{"id":72,"contact":73,"descriptor":82,"extension":5,"fullName":83,"meta":84,"metrics":85,"name":98,"partners":99,"qualification":104,"socialMedia":112,"stem":129,"tagline":130,"testimonials":131,"whySoftoft":144,"__hash__":157},"company_en/en/_data/company.yml",{"email":74,"appointmentUrl":75,"googleReviewsUrl":76,"address":77},"info@softoft.de","https://calendar.app.google/fXPHuhqQvx9Gf4LT9","https://www.google.com/maps/place/SoftOft/@50.0040865,8.2451374,17z/data=!3m1!4b1!4m6!3m5!1s0x47bd97c3c5e853d3:0x63a648317d57a53d!8m2!3d50.0040865!4d8.2451374!16s%2Fg%2F11rg8q5d69",{"street":78,"city":79,"zip":80,"country":81},"Am Judensand 7","Mainz","55122","Germany","Ticket System & AI Automation","Softoft Tobias Bück Einzelunternehmen",{},[86,89,92,95],{"value":87,"label":88},"5+","Years of ticket-system experience",{"value":90,"label":91},"5.0 ★","Rating on Google",{"value":93,"label":94},"Top 1000","Kaggle Datasets worldwide",{"value":96,"label":97},"100%","On-premise & privacy-first","Tobias Bück",[100],{"name":101,"description":102,"url":103},"Open Ticket AI","AI-powered ticket classification and routing for on-prem OTOBO/Znuny via REST APIs and Python SDKs","https://openticketai.com",{"heading":105,"intro":106,"bullets":107},"Who is this for?","Best fit for teams with clear ticket-system goals:",[108,109,110,111],"On-premise ticket systems","OTOBO or Znuny teams","REST APIs & Python SDK integrations",">500 tickets per month or AI automation plans",[113,117,121,125],{"platform":114,"url":115,"icon":116},"LinkedIn","https://www.linkedin.com/company/softoft-it-services/","fa-brands:linkedin",{"platform":118,"url":119,"icon":120},"GitHub","https://github.com/Softoft","fa-brands:github",{"platform":122,"url":123,"icon":124},"Kaggle","https://www.kaggle.com/tobiasbueck","simple-icons:kaggle",{"platform":126,"url":127,"icon":128},"Medium","https://medium.com/@softoft","fa-brands:medium","en/_data/company","Your Partner for On-Prem Ticket Automation & AI",[132,137,141],{"text":133,"name":134,"role":135,"company":136},"Tobi did some fine-tuning on our OTOBO ticket system. It was quick and uncomplicated. He knows what he is doing and implements it with creative solutions. Would do it again any time. Thank you!","Dennis Lohmann","Google review","",{"text":138,"name":139,"role":135,"company":140},"Softoft helped us (Vianova Service GmbH) set up the OTOBO ticket system. Everything worked out well.","Reinhard Sczech","Vianova Service GmbH",{"text":142,"name":143,"role":135,"company":136},"SoftOft helped us further develop our website. Fast, uncomplicated, affordable! Happy to work with them again!","Jochen Petersen",[145,148,151,154],{"icon":146,"text":147},"heroicons:star-20-solid","Less manual triage — your team replies faster",{"icon":149,"text":150},"heroicons:rocket-launch-20-solid","Live in weeks, not months",{"icon":152,"text":153},"heroicons:shield-check-20-solid","Your data never leaves your servers",{"icon":155,"text":156},"heroicons:user-20-solid","A direct line to the expert — no middlemen","4ybQcZov1bdfjDMPhJjfYr_SrSBATncI9Z8P9mqP32k",{"id":159,"title":160,"author":98,"blogId":161,"body":162,"canonicalUrl":731,"description":732,"extension":733,"externalUrl":734,"layout":734,"mainImage":735,"meta":736,"mobileImage":735,"navigation":433,"openItsmHubRelated":737,"openItsmHubUrl":740,"order":744,"path":745,"publishedAt":746,"seo":747,"stem":748,"tags":749,"__hash__":756},"blog_en/en/blog/otobo-openticketai-connector.md","Open Ticket AI Connector: Extending the OTOBO and Znuny Generic Interface API","otobo-openticketai-connector",{"type":163,"value":164,"toc":723},"minimark",[165,170,183,195,213,218,221,248,261,265,272,394,397,402,405,409,412,598,608,618,622,629,632,644,648,689,700,704,707,719],[166,167,169],"h1",{"id":168},"we-have-the-connector-api-extensions-for-otobo-and-znuny","We Have the Connector: API Extensions for OTOBO and Znuny",[171,172,173,174,178,179,182],"p",{},"Stock OTOBO and Znuny already expose ticket create, get, search, and update through the ",[175,176,177],"strong",{},"Generic Interface",". That is enough to move tickets — it is not enough for an AI runtime or Studio that must ",[175,180,181],{},"sync queues, states, priorities, services, types, Dynamic Fields, and FAQ"," before it can classify or route anything.",[171,184,185,186,189,190,194],{},"That is why we ship the ",[175,187,188],{},"Open Ticket AI Connector",": a package that installs one REST webservice named ",[191,192,193],"code",{},"OpenTicketAI"," and registers extra Generic Interface operations on top of the built-in ticket API.",[171,196,197,198,204,205,208,209,212],{},"The connector is how ",[199,200,101],"a",{"href":201,"rel":202},"https://openticketai.com/",[203],"nofollow"," talks to ",[175,206,207],{},"OTOBO 11"," and ",[175,210,211],{},"Znuny"," on-premise. No SaaS hop, no second ticket store — the ticket system stays the system of record.",[214,215,217],"h2",{"id":216},"what-the-connector-installs","What the connector installs",[171,219,220],{},"On install the package does two things:",[222,223,224,240],"ol",{},[225,226,227,228,231,232,235,236,239],"li",{},"Creates a ",[175,229,230],{},"restricted API agent"," used only by Open Ticket AI (OTOBO default login ",[191,233,234],{},"otai-webservice","; Znuny default ",[191,237,238],{},"open_ticket_ai",").",[225,241,242,243,247],{},"Imports a single Generic Interface REST webservice ",[175,244,245],{},[191,246,193],{},", locked to that user so other agents cannot call it.",[171,249,250,251,256,257,260],{},"It also ensures an ",[175,252,253],{},[191,254,255],{},"ai-agent"," group exists. FAQ categories you want the AI to search must be granted to that group (in addition to ",[191,258,259],{},"users"," for human agents).",[214,262,264],{"id":263},"ticket-operations-plus-catalogue-extensions","Ticket operations plus catalogue extensions",[171,266,267,268,271],{},"The webservice keeps the familiar ticket routes and adds catalogue operations we implemented as ",[191,269,270],{},"TicketAICatalog::*"," modules:",[273,274,275,291],"table",{},[276,277,278],"thead",{},[279,280,281,285,288],"tr",{},[282,283,284],"th",{},"Operation",[282,286,287],{},"Route",[282,289,290],{},"Role",[292,293,294,318,337,353,370,383],"tbody",{},[279,295,296,300,315],{},[297,298,299],"td",{},"TicketCreate / Get / Search / Update",[297,301,302,305,306,305,309,305,312],{},[191,303,304],{},"/ticket-create",", ",[191,307,308],{},"/ticket-get",[191,310,311],{},"/ticket-search",[191,313,314],{},"/ticket-update",[297,316,317],{},"Core ticket API",[279,319,320,323,334],{},[297,321,322],{},"QueueList, StateList, PriorityList",[297,324,325,305,328,305,331],{},[191,326,327],{},"/queue-list",[191,329,330],{},"/state-list",[191,332,333],{},"/priority-list",[297,335,336],{},"Routing catalogue",[279,338,339,342,350],{},[297,340,341],{},"ServiceList, TypeList",[297,343,344,305,347],{},[191,345,346],{},"/service-list",[191,348,349],{},"/type-list",[297,351,352],{},"Classification values",[279,354,355,358,367],{},[297,356,357],{},"DynamicFieldList / Values / Create",[297,359,360,305,363,366],{},[191,361,362],{},"/dynamic-field-list",[191,364,365],{},"/dynamic-field-values",", …",[297,368,369],{},"Field sync and dropdown setup",[279,371,372,375,380],{},[297,373,374],{},"FAQSearch",[297,376,377],{},[191,378,379],{},"/faq-search",[297,381,382],{},"Knowledge lookup for the AI",[279,384,385,388,391],{},[297,386,387],{},"AgentCount",[297,389,390],{},"licence / sizing helper",[297,392,393],{},"Count valid agents",[171,395,396],{},"Base URL:",[171,398,399],{},[191,400,401],{},"\u003Chost>/\u003Cotobo|znuny>/nph-genericinterface.pl/Webservice/OpenTicketAI/\u003Croute>",[171,403,404],{},"Authentication is HTTP Basic Auth with the API agent credentials.",[214,406,408],{"id":407},"how-an-extension-looks-in-code","How an extension looks in code",[171,410,411],{},"Each catalogue operation is a Generic Interface module. After auth it reads native OTOBO/Znuny objects and returns a stable JSON list — here, queues:",[413,414,418],"pre",{"className":415,"code":416,"language":417,"meta":136,"style":136},"language-perl shiki shiki-themes github-light github-dark","package Kernel::GenericInterface::Operation::TicketAICatalog::QueueList;\n\nuse parent qw(Kernel::GenericInterface::Operation::TicketAICatalog::Base);\n\nsub Run {\n    my ( $Self, %Param ) = @_;\n\n    my ( $UserID, $Error ) = $Self->_AuthOrError(%Param);\n    return $Error if $Error;\n\n    my $QueueObject = $Kernel::OM->Get('Kernel::System::Queue');\n    my %Queues      = $QueueObject->QueueList( Valid => 0 );\n\n    my @Items;\n    for my $QueueID ( sort { $a \u003C=> $b } keys %Queues ) {\n        my %Queue = $QueueObject->QueueGet( ID => $QueueID );\n        next if !%Queue;\n        push @Items, {\n            ID      => $QueueID + 0,\n            Name    => $Queue{Name} // $Queues{$QueueID},\n            Comment => $Queue{Comment} // '',\n            Valid   => ( ( $Queue{ValidID} // 1 ) == 1 ) ? 1 : 0,\n        };\n    }\n\n    return {\n        Success => 1,\n        Data    => { Item => \\@Items },\n    };\n}\n","perl",[191,419,420,428,435,441,446,452,458,463,469,475,480,486,492,497,503,509,515,521,527,533,539,545,551,557,563,568,574,580,586,592],{"__ignoreMap":136},[421,422,425],"span",{"class":423,"line":424},"line",1,[421,426,427],{},"package Kernel::GenericInterface::Operation::TicketAICatalog::QueueList;\n",[421,429,431],{"class":423,"line":430},2,[421,432,434],{"emptyLinePlaceholder":433},true,"\n",[421,436,438],{"class":423,"line":437},3,[421,439,440],{},"use parent qw(Kernel::GenericInterface::Operation::TicketAICatalog::Base);\n",[421,442,444],{"class":423,"line":443},4,[421,445,434],{"emptyLinePlaceholder":433},[421,447,449],{"class":423,"line":448},5,[421,450,451],{},"sub Run {\n",[421,453,455],{"class":423,"line":454},6,[421,456,457],{},"    my ( $Self, %Param ) = @_;\n",[421,459,461],{"class":423,"line":460},7,[421,462,434],{"emptyLinePlaceholder":433},[421,464,466],{"class":423,"line":465},8,[421,467,468],{},"    my ( $UserID, $Error ) = $Self->_AuthOrError(%Param);\n",[421,470,472],{"class":423,"line":471},9,[421,473,474],{},"    return $Error if $Error;\n",[421,476,478],{"class":423,"line":477},10,[421,479,434],{"emptyLinePlaceholder":433},[421,481,483],{"class":423,"line":482},11,[421,484,485],{},"    my $QueueObject = $Kernel::OM->Get('Kernel::System::Queue');\n",[421,487,489],{"class":423,"line":488},12,[421,490,491],{},"    my %Queues      = $QueueObject->QueueList( Valid => 0 );\n",[421,493,495],{"class":423,"line":494},13,[421,496,434],{"emptyLinePlaceholder":433},[421,498,500],{"class":423,"line":499},14,[421,501,502],{},"    my @Items;\n",[421,504,506],{"class":423,"line":505},15,[421,507,508],{},"    for my $QueueID ( sort { $a \u003C=> $b } keys %Queues ) {\n",[421,510,512],{"class":423,"line":511},16,[421,513,514],{},"        my %Queue = $QueueObject->QueueGet( ID => $QueueID );\n",[421,516,518],{"class":423,"line":517},17,[421,519,520],{},"        next if !%Queue;\n",[421,522,524],{"class":423,"line":523},18,[421,525,526],{},"        push @Items, {\n",[421,528,530],{"class":423,"line":529},19,[421,531,532],{},"            ID      => $QueueID + 0,\n",[421,534,536],{"class":423,"line":535},20,[421,537,538],{},"            Name    => $Queue{Name} // $Queues{$QueueID},\n",[421,540,542],{"class":423,"line":541},21,[421,543,544],{},"            Comment => $Queue{Comment} // '',\n",[421,546,548],{"class":423,"line":547},22,[421,549,550],{},"            Valid   => ( ( $Queue{ValidID} // 1 ) == 1 ) ? 1 : 0,\n",[421,552,554],{"class":423,"line":553},23,[421,555,556],{},"        };\n",[421,558,560],{"class":423,"line":559},24,[421,561,562],{},"    }\n",[421,564,566],{"class":423,"line":565},25,[421,567,434],{"emptyLinePlaceholder":433},[421,569,571],{"class":423,"line":570},26,[421,572,573],{},"    return {\n",[421,575,577],{"class":423,"line":576},27,[421,578,579],{},"        Success => 1,\n",[421,581,583],{"class":423,"line":582},28,[421,584,585],{},"        Data    => { Item => \\@Items },\n",[421,587,589],{"class":423,"line":588},29,[421,590,591],{},"    };\n",[421,593,595],{"class":423,"line":594},30,[421,596,597],{},"}\n",[171,599,600,601,604,605,607],{},"The same pattern covers states, priorities, services, types, and Dynamic Fields. ",[175,602,603],{},"DynamicFieldCreate"," can create or update a Ticket dropdown field and enable it on the usual agent screens. ",[175,606,374],{}," queries customer-visible FAQ articles and fails softly if the FAQ package is not installed.",[171,609,610,611,208,614,617],{},"Operations are registered in SysConfig as Generic Interface modules, for example ",[191,612,613],{},"TicketAICatalog::QueueList",[191,615,616],{},"TicketAICatalog::FAQSearch",".",[214,619,621],{"id":620},"why-this-matters-for-ai-on-the-helpdesk","Why this matters for AI on the helpdesk",[171,623,624,625,628],{},"Without catalogue endpoints, an external engine can only guess queue names from ticket text. With the connector, Studio and the runtime ",[175,626,627],{},"sync the live catalogue",", map predictions to real IDs, and write back through TicketUpdate — including Dynamic Fields.",[171,630,631],{},"Related packages on the same stack:",[633,634,635,641],"ul",{},[225,636,637,640],{},[175,638,639],{},"OTAIStudio"," — SSO from the agent UI into Open Ticket AI Studio (requires this connector).",[225,642,643],{},"Optional agent screens for attributes and human review of AI suggestions.",[214,645,647],{"id":646},"otobo-and-znuny","OTOBO and Znuny",[273,649,650,663],{},[276,651,652],{},[279,653,654,657,660],{},[282,655,656],{},"System",[282,658,659],{},"Package",[282,661,662],{},"Typical API login",[292,664,665,677],{},[279,666,667,670,673],{},[297,668,669],{},"OTOBO 11.0.x",[297,671,672],{},"Open Ticket AI (OTOBO)",[297,674,675],{},[191,676,234],{},[279,678,679,682,685],{},[297,680,681],{},"Znuny 7.x / LTS 6.5",[297,683,684],{},"Open Ticket AI (Znuny)",[297,686,687],{},[191,688,238],{},[171,690,691,692,695,696,699],{},"The Generic Interface operation names stay the same on both systems. OTOBO reads the API password from the process environment (",[191,693,694],{},"OTAI_TICKETSYSTEM_PASSWORD","); Znuny uses SysConfig (",[191,697,698],{},"OpenTicketAIConnector::AgentPassword",") before install.",[214,701,703],{"id":702},"next-step","Next step",[171,705,706],{},"If you run OTOBO or Znuny and want on-prem ticket AI with a proper API — not a brittle scrape of the agent UI — this connector is the integration layer we use in production.",[171,708,709,710,714,715,617],{},"Read more about the product on ",[199,711,713],{"href":201,"rel":712},[203],"openticketai.com"," or ",[199,716,718],{"href":717},"/en/contact/","get in touch",[720,721,722],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":136,"searchDepth":430,"depth":430,"links":724},[725,726,727,728,729,730],{"id":216,"depth":430,"text":217},{"id":263,"depth":430,"text":264},{"id":407,"depth":430,"text":408},{"id":620,"depth":430,"text":621},{"id":646,"depth":430,"text":647},{"id":702,"depth":430,"text":703},"https://openticketai.com/en/docs/otai-runtime/otobo-znuny-plugin-setup","Softoft ships an Open Ticket AI connector package that extends the Generic Interface of OTOBO and Znuny with catalogue, FAQ, and Dynamic Field operations — a dedicated REST API for on-prem ticket AI.","md",null,"/images/blog/open-source-ticket-systems-ai.webp",{},[738,741],{"title":739,"url":740},"Open Ticket AI in the Hub catalog","https://openitsmhub.com/packages/open-ticket-ai-runtime",{"title":742,"url":743},"Helpdesk AI, APIs, and data protection","https://openitsmhub.com/blog/opensource-helpdesk-ki-apis-automation-datenschutz",1204,"/en/blog/otobo-openticketai-connector","2026-08-27",{"title":160,"description":732},"en/blog/otobo-openticketai-connector",[750,751,752,753,754,755],"otobo","znuny","openticketai","api","generic-interface","ticket-system","UVaBRJYF_sV86WumTp35N-OKJyOMMRjyNHCoSUIQbEc",1789462343624]