[{"data":1,"prerenderedAt":2072},["ShallowReactive",2],{"blog-post-python-automation-ticketsysteme-rest-api-en":3},{"id":4,"title":5,"body":6,"date":2062,"description":2063,"draft":2064,"extension":2065,"meta":2066,"navigation":156,"path":2068,"seo":2069,"stem":2070,"__hash__":2071},"blogEn\u002Fblog\u002Fpython-automation-ticketsysteme-rest-api.md","Ticketing System Automation with Python: REST APIs, Libraries, and Practical Patterns",{"type":7,"value":8,"toc":2041},"minimark",[9,13,30,33,38,105,107,111,116,123,433,439,445,450,453,701,706,726,728,732,739,743,1042,1046,1049,1067,1071,1087,1089,1093,1097,1284,1288,1455,1459,1565,1567,1571,1574,1827,1829,1833,1836,1900,1902,1906,1989,1991,1995,2001,2021,2029,2031,2037],[10,11,5],"h1",{"id":12},"ticketing-system-automation-with-python-rest-apis-libraries-and-practical-patterns",[14,15,16,17,21,22,25,26,29],"p",{},"Python is the lingua franca of system automation, and open-source ticketing systems like ",[18,19,20],"strong",{},"Zammad",", ",[18,23,24],{},"OTOBO",", and ",[18,27,28],{},"Znuny"," (an OTRS fork) offer a wide range of integration options. This article breaks down available Python clients, official APIs, and proven patterns for recurring automation tasks.",[31,32],"hr",{},[34,35,37],"h2",{"id":36},"the-three-paths-to-python-integration","The Three Paths to Python Integration",[39,40,41,57],"table",{},[42,43,44],"thead",{},[45,46,47,51,54],"tr",{},[48,49,50],"th",{},"Approach",[48,52,53],{},"When to Use",[48,55,56],{},"Complexity",[58,59,60,74,91],"tbody",{},[45,61,62,68,71],{},[63,64,65],"td",{},[18,66,67],{},"Official Python Client Library",[63,69,70],{},"Quick start, documented endpoints",[63,72,73],{},"Low",[45,75,76,85,88],{},[63,77,78],{},[18,79,80,81],{},"Direct REST API with ",[82,83,84],"code",{},"requests",[63,86,87],{},"Full control, custom endpoints, debugging",[63,89,90],{},"Medium",[45,92,93,99,102],{},[63,94,95,98],{},[18,96,97],{},"Wrapper\u002FETL Frameworks"," (e.g., open-ticket-ai)",[63,100,101],{},"Multi-system automation, pipelines, RAG",[63,103,104],{},"High",[31,106],{},[34,108,110],{"id":109},"zammad-zammad-py-and-the-rest-api","Zammad: Zammad-Py and the REST API",[112,113,115],"h3",{"id":114},"zammad-py-community-client","Zammad-Py (Community Client)",[14,117,118,119,122],{},"The ",[82,120,121],{},"zammad_py"," library provides an object-oriented layer over the Zammad REST API:",[124,125,130],"pre",{"className":126,"code":127,"language":128,"meta":129,"style":129},"language-python shiki shiki-themes one-dark-pro","from zammad_py import ZammadAPI\n\nclient = ZammadAPI(\n    url=\"https:\u002F\u002Fhelpdesk.example.com\u002Fapi\u002Fv1\",\n    http_token=\"your_api_token\"\n)\n\n# Fetch tickets\nfor ticket in client.ticket.all():\n    print(f\"{ticket['number']}: {ticket['title']}\")\n\n# Create a ticket\nticket = client.ticket.create({\n    \"title\": \"Server Alert: CPU Load\",\n    \"group\": \"IT-Operations\",\n    \"customer\": \"monitoring@example.com\",\n    \"article\": {\n        \"subject\": \"Alert\",\n        \"body\": \"CPU usage exceeded 90% on server-01\",\n        \"type\": \"note\",\n        \"internal\": False\n    }\n})\n","python","",[82,131,132,151,158,175,191,202,208,213,220,241,290,295,301,317,330,343,356,365,378,397,410,421,427],{"__ignoreMap":129},[133,134,137,141,145,148],"span",{"class":135,"line":136},"line",1,[133,138,140],{"class":139},"seHd6","from",[133,142,144],{"class":143},"sn6KH"," zammad_py ",[133,146,147],{"class":139},"import",[133,149,150],{"class":143}," ZammadAPI\n",[133,152,154],{"class":135,"line":153},2,[133,155,157],{"emptyLinePlaceholder":156},true,"\n",[133,159,161,164,168,172],{"class":135,"line":160},3,[133,162,163],{"class":143},"client ",[133,165,167],{"class":166},"sjrmR","=",[133,169,171],{"class":170},"sVbv2"," ZammadAPI",[133,173,174],{"class":143},"(\n",[133,176,178,182,184,188],{"class":135,"line":177},4,[133,179,181],{"class":180},"s_ZVi","    url",[133,183,167],{"class":166},[133,185,187],{"class":186},"subq3","\"https:\u002F\u002Fhelpdesk.example.com\u002Fapi\u002Fv1\"",[133,189,190],{"class":143},",\n",[133,192,194,197,199],{"class":135,"line":193},5,[133,195,196],{"class":180},"    http_token",[133,198,167],{"class":166},[133,200,201],{"class":186},"\"your_api_token\"\n",[133,203,205],{"class":135,"line":204},6,[133,206,207],{"class":143},")\n",[133,209,211],{"class":135,"line":210},7,[133,212,157],{"emptyLinePlaceholder":156},[133,214,216],{"class":135,"line":215},8,[133,217,219],{"class":218},"sV9Aq","# Fetch tickets\n",[133,221,223,226,229,232,235,238],{"class":135,"line":222},9,[133,224,225],{"class":139},"for",[133,227,228],{"class":143}," ticket ",[133,230,231],{"class":139},"in",[133,233,234],{"class":143}," client.ticket.",[133,236,237],{"class":170},"all",[133,239,240],{"class":143},"():\n",[133,242,244,247,250,253,256,260,263,266,269,272,275,277,279,282,284,286,288],{"class":135,"line":243},10,[133,245,246],{"class":166},"    print",[133,248,249],{"class":143},"(",[133,251,252],{"class":139},"f",[133,254,255],{"class":186},"\"",[133,257,259],{"class":258},"sVC51","{",[133,261,262],{"class":143},"ticket[",[133,264,265],{"class":186},"'number'",[133,267,268],{"class":143},"]",[133,270,271],{"class":258},"}",[133,273,274],{"class":186},": ",[133,276,259],{"class":258},[133,278,262],{"class":143},[133,280,281],{"class":186},"'title'",[133,283,268],{"class":143},[133,285,271],{"class":258},[133,287,255],{"class":186},[133,289,207],{"class":143},[133,291,293],{"class":135,"line":292},11,[133,294,157],{"emptyLinePlaceholder":156},[133,296,298],{"class":135,"line":297},12,[133,299,300],{"class":218},"# Create a ticket\n",[133,302,304,307,309,311,314],{"class":135,"line":303},13,[133,305,306],{"class":143},"ticket ",[133,308,167],{"class":166},[133,310,234],{"class":143},[133,312,313],{"class":170},"create",[133,315,316],{"class":143},"({\n",[133,318,320,323,325,328],{"class":135,"line":319},14,[133,321,322],{"class":186},"    \"title\"",[133,324,274],{"class":143},[133,326,327],{"class":186},"\"Server Alert: CPU Load\"",[133,329,190],{"class":143},[133,331,333,336,338,341],{"class":135,"line":332},15,[133,334,335],{"class":186},"    \"group\"",[133,337,274],{"class":143},[133,339,340],{"class":186},"\"IT-Operations\"",[133,342,190],{"class":143},[133,344,346,349,351,354],{"class":135,"line":345},16,[133,347,348],{"class":186},"    \"customer\"",[133,350,274],{"class":143},[133,352,353],{"class":186},"\"monitoring@example.com\"",[133,355,190],{"class":143},[133,357,359,362],{"class":135,"line":358},17,[133,360,361],{"class":186},"    \"article\"",[133,363,364],{"class":143},": {\n",[133,366,368,371,373,376],{"class":135,"line":367},18,[133,369,370],{"class":186},"        \"subject\"",[133,372,274],{"class":143},[133,374,375],{"class":186},"\"Alert\"",[133,377,190],{"class":143},[133,379,381,384,386,389,392,395],{"class":135,"line":380},19,[133,382,383],{"class":186},"        \"body\"",[133,385,274],{"class":143},[133,387,388],{"class":186},"\"CPU usage exceeded 90",[133,390,391],{"class":258},"% o",[133,393,394],{"class":186},"n server-01\"",[133,396,190],{"class":143},[133,398,400,403,405,408],{"class":135,"line":399},20,[133,401,402],{"class":186},"        \"type\"",[133,404,274],{"class":143},[133,406,407],{"class":186},"\"note\"",[133,409,190],{"class":143},[133,411,413,416,418],{"class":135,"line":412},21,[133,414,415],{"class":186},"        \"internal\"",[133,417,274],{"class":143},[133,419,420],{"class":258},"False\n",[133,422,424],{"class":135,"line":423},22,[133,425,426],{"class":143},"    }\n",[133,428,430],{"class":135,"line":429},23,[133,431,432],{"class":143},"})\n",[14,434,435,438],{},[18,436,437],{},"Pros:"," Typical CRUD operations abstracted, error handling included, active community.",[14,440,441,444],{},[18,442,443],{},"Limitations:"," Not all API features (e.g., Core Workflows, Object Manager changes) are mapped.",[112,446,80,448],{"id":447},"direct-rest-api-with-requests",[82,449,84],{},[14,451,452],{},"For advanced scenarios (webhooks, tags, time accounting), direct API access is recommended:",[124,454,456],{"className":126,"code":455,"language":128,"meta":129,"style":129},"import requests\n\nheaders = {\n    \"Authorization\": \"Bearer your_token\",\n    \"Content-Type\": \"application\u002Fjson\"\n}\n\n# Search with query\nresponse = requests.get(\n    \"https:\u002F\u002Fhelpdesk.example.com\u002Fapi\u002Fv1\u002Ftickets\u002Fsearch\",\n    headers=headers,\n    params={\"query\": \"state:new AND priority:3\", \"limit\": 50}\n)\n\n# Bulk update multiple tickets\ntickets = response.json()[\"assets\"][\"Ticket\"]\nfor ticket_id in tickets:\n    requests.put(\n        f\"https:\u002F\u002Fhelpdesk.example.com\u002Fapi\u002Fv1\u002Ftickets\u002F{ticket_id}\",\n        headers=headers,\n        json={\"state\": \"open\", \"owner\": \"admin@example.com\"}\n    )\n",[82,457,458,465,469,479,491,501,506,510,515,530,537,547,576,580,584,589,617,629,639,658,667,696],{"__ignoreMap":129},[133,459,460,462],{"class":135,"line":136},[133,461,147],{"class":139},[133,463,464],{"class":143}," requests\n",[133,466,467],{"class":135,"line":153},[133,468,157],{"emptyLinePlaceholder":156},[133,470,471,474,476],{"class":135,"line":160},[133,472,473],{"class":143},"headers ",[133,475,167],{"class":166},[133,477,478],{"class":143}," {\n",[133,480,481,484,486,489],{"class":135,"line":177},[133,482,483],{"class":186},"    \"Authorization\"",[133,485,274],{"class":143},[133,487,488],{"class":186},"\"Bearer your_token\"",[133,490,190],{"class":143},[133,492,493,496,498],{"class":135,"line":193},[133,494,495],{"class":186},"    \"Content-Type\"",[133,497,274],{"class":143},[133,499,500],{"class":186},"\"application\u002Fjson\"\n",[133,502,503],{"class":135,"line":204},[133,504,505],{"class":143},"}\n",[133,507,508],{"class":135,"line":210},[133,509,157],{"emptyLinePlaceholder":156},[133,511,512],{"class":135,"line":215},[133,513,514],{"class":218},"# Search with query\n",[133,516,517,520,522,525,528],{"class":135,"line":222},[133,518,519],{"class":143},"response ",[133,521,167],{"class":166},[133,523,524],{"class":143}," requests.",[133,526,527],{"class":170},"get",[133,529,174],{"class":143},[133,531,532,535],{"class":135,"line":243},[133,533,534],{"class":186},"    \"https:\u002F\u002Fhelpdesk.example.com\u002Fapi\u002Fv1\u002Ftickets\u002Fsearch\"",[133,536,190],{"class":143},[133,538,539,542,544],{"class":135,"line":292},[133,540,541],{"class":180},"    headers",[133,543,167],{"class":166},[133,545,546],{"class":143},"headers,\n",[133,548,549,552,554,556,559,561,564,566,569,571,574],{"class":135,"line":297},[133,550,551],{"class":180},"    params",[133,553,167],{"class":166},[133,555,259],{"class":143},[133,557,558],{"class":186},"\"query\"",[133,560,274],{"class":143},[133,562,563],{"class":186},"\"state:new AND priority:3\"",[133,565,21],{"class":143},[133,567,568],{"class":186},"\"limit\"",[133,570,274],{"class":143},[133,572,573],{"class":258},"50",[133,575,505],{"class":143},[133,577,578],{"class":135,"line":303},[133,579,207],{"class":143},[133,581,582],{"class":135,"line":319},[133,583,157],{"emptyLinePlaceholder":156},[133,585,586],{"class":135,"line":332},[133,587,588],{"class":218},"# Bulk update multiple tickets\n",[133,590,591,594,596,599,602,605,608,611,614],{"class":135,"line":345},[133,592,593],{"class":143},"tickets ",[133,595,167],{"class":166},[133,597,598],{"class":143}," response.",[133,600,601],{"class":170},"json",[133,603,604],{"class":143},"()[",[133,606,607],{"class":186},"\"assets\"",[133,609,610],{"class":143},"][",[133,612,613],{"class":186},"\"Ticket\"",[133,615,616],{"class":143},"]\n",[133,618,619,621,624,626],{"class":135,"line":358},[133,620,225],{"class":139},[133,622,623],{"class":143}," ticket_id ",[133,625,231],{"class":139},[133,627,628],{"class":143}," tickets:\n",[133,630,631,634,637],{"class":135,"line":367},[133,632,633],{"class":143},"    requests.",[133,635,636],{"class":170},"put",[133,638,174],{"class":143},[133,640,641,644,647,649,652,654,656],{"class":135,"line":380},[133,642,643],{"class":139},"        f",[133,645,646],{"class":186},"\"https:\u002F\u002Fhelpdesk.example.com\u002Fapi\u002Fv1\u002Ftickets\u002F",[133,648,259],{"class":258},[133,650,651],{"class":143},"ticket_id",[133,653,271],{"class":258},[133,655,255],{"class":186},[133,657,190],{"class":143},[133,659,660,663,665],{"class":135,"line":399},[133,661,662],{"class":180},"        headers",[133,664,167],{"class":166},[133,666,546],{"class":143},[133,668,669,672,674,676,679,681,684,686,689,691,694],{"class":135,"line":412},[133,670,671],{"class":180},"        json",[133,673,167],{"class":166},[133,675,259],{"class":143},[133,677,678],{"class":186},"\"state\"",[133,680,274],{"class":143},[133,682,683],{"class":186},"\"open\"",[133,685,21],{"class":143},[133,687,688],{"class":186},"\"owner\"",[133,690,274],{"class":143},[133,692,693],{"class":186},"\"admin@example.com\"",[133,695,505],{"class":143},[133,697,698],{"class":135,"line":423},[133,699,700],{"class":143},"    )\n",[14,702,703],{},[18,704,705],{},"Resources:",[707,708,709,719],"ul",{},[710,711,712],"li",{},[713,714,718],"a",{"href":715,"rel":716},"https:\u002F\u002Fpypi.org\u002Fproject\u002Fzammad-py\u002F",[717],"nofollow","zammad_py on PyPI",[710,720,721],{},[713,722,725],{"href":723,"rel":724},"https:\u002F\u002Fdocs.zammad.com\u002Fen\u002Flatest\u002Fapi\u002Fintro.html",[717],"Zammad REST API Docs",[31,727],{},[34,729,731],{"id":730},"otobo-znuny-the-opm-interface-and-genericinterface","OTOBO & Znuny: The OPM Interface and GenericInterface",[14,733,734,735,738],{},"OTOBO and Znuny (as OTRS forks) use a similar architecture: the ",[18,736,737],{},"GenericInterface"," provides REST\u002FSOAP web services that can be accessed via Python.",[112,740,742],{"id":741},"pattern-session-based-authentication","Pattern: Session-Based Authentication",[124,744,746],{"className":126,"code":745,"language":128,"meta":129,"style":129},"import requests\n\n# 1. Obtain SessionToken\nsession_resp = requests.post(\n    \"https:\u002F\u002Fotobo.example.com\u002Fotobo\u002Frpc.pl\",\n    json={\n        \"UserLogin\": \"api_user\",\n        \"Password\": \"api_pass\"\n    }\n)\nsession_token = session_resp.json()[\"SessionID\"]\n\n# 2. Create ticket\nticket_create = requests.post(\n    \"https:\u002F\u002Fotobo.example.com\u002Fotobo\u002Fnph-genericinterface.pl\u002FWebservice\u002FTicketConnectorREST\u002FTicket\",\n    headers={\"Authorization\": f\"Token {session_token}\"},\n    json={\n        \"Ticket\": {\n            \"Title\": \"API-Generated Alert\",\n            \"Queue\": \"IT-Support\",\n            \"State\": \"new\",\n            \"Priority\": \"3 normal\",\n            \"CustomerUser\": \"monitoring\"\n        },\n        \"Article\": {\n            \"Subject\": \"Automated Alert\",\n            \"Body\": \"Alert details...\",\n            \"ContentType\": \"text\u002Fplain; charset=utf8\"\n        }\n    }\n)\n",[82,747,748,754,758,763,777,784,794,806,816,820,824,843,847,852,865,872,902,910,917,929,941,953,965,975,981,989,1002,1015,1026,1032,1037],{"__ignoreMap":129},[133,749,750,752],{"class":135,"line":136},[133,751,147],{"class":139},[133,753,464],{"class":143},[133,755,756],{"class":135,"line":153},[133,757,157],{"emptyLinePlaceholder":156},[133,759,760],{"class":135,"line":160},[133,761,762],{"class":218},"# 1. Obtain SessionToken\n",[133,764,765,768,770,772,775],{"class":135,"line":177},[133,766,767],{"class":143},"session_resp ",[133,769,167],{"class":166},[133,771,524],{"class":143},[133,773,774],{"class":170},"post",[133,776,174],{"class":143},[133,778,779,782],{"class":135,"line":193},[133,780,781],{"class":186},"    \"https:\u002F\u002Fotobo.example.com\u002Fotobo\u002Frpc.pl\"",[133,783,190],{"class":143},[133,785,786,789,791],{"class":135,"line":204},[133,787,788],{"class":180},"    json",[133,790,167],{"class":166},[133,792,793],{"class":143},"{\n",[133,795,796,799,801,804],{"class":135,"line":210},[133,797,798],{"class":186},"        \"UserLogin\"",[133,800,274],{"class":143},[133,802,803],{"class":186},"\"api_user\"",[133,805,190],{"class":143},[133,807,808,811,813],{"class":135,"line":215},[133,809,810],{"class":186},"        \"Password\"",[133,812,274],{"class":143},[133,814,815],{"class":186},"\"api_pass\"\n",[133,817,818],{"class":135,"line":222},[133,819,426],{"class":143},[133,821,822],{"class":135,"line":243},[133,823,207],{"class":143},[133,825,826,829,831,834,836,838,841],{"class":135,"line":292},[133,827,828],{"class":143},"session_token ",[133,830,167],{"class":166},[133,832,833],{"class":143}," session_resp.",[133,835,601],{"class":170},[133,837,604],{"class":143},[133,839,840],{"class":186},"\"SessionID\"",[133,842,616],{"class":143},[133,844,845],{"class":135,"line":297},[133,846,157],{"emptyLinePlaceholder":156},[133,848,849],{"class":135,"line":303},[133,850,851],{"class":218},"# 2. Create ticket\n",[133,853,854,857,859,861,863],{"class":135,"line":319},[133,855,856],{"class":143},"ticket_create ",[133,858,167],{"class":166},[133,860,524],{"class":143},[133,862,774],{"class":170},[133,864,174],{"class":143},[133,866,867,870],{"class":135,"line":332},[133,868,869],{"class":186},"    \"https:\u002F\u002Fotobo.example.com\u002Fotobo\u002Fnph-genericinterface.pl\u002FWebservice\u002FTicketConnectorREST\u002FTicket\"",[133,871,190],{"class":143},[133,873,874,876,878,880,883,885,887,890,892,895,897,899],{"class":135,"line":345},[133,875,541],{"class":180},[133,877,167],{"class":166},[133,879,259],{"class":143},[133,881,882],{"class":186},"\"Authorization\"",[133,884,274],{"class":143},[133,886,252],{"class":139},[133,888,889],{"class":186},"\"Token ",[133,891,259],{"class":258},[133,893,894],{"class":143},"session_token",[133,896,271],{"class":258},[133,898,255],{"class":186},[133,900,901],{"class":143},"},\n",[133,903,904,906,908],{"class":135,"line":358},[133,905,788],{"class":180},[133,907,167],{"class":166},[133,909,793],{"class":143},[133,911,912,915],{"class":135,"line":367},[133,913,914],{"class":186},"        \"Ticket\"",[133,916,364],{"class":143},[133,918,919,922,924,927],{"class":135,"line":380},[133,920,921],{"class":186},"            \"Title\"",[133,923,274],{"class":143},[133,925,926],{"class":186},"\"API-Generated Alert\"",[133,928,190],{"class":143},[133,930,931,934,936,939],{"class":135,"line":399},[133,932,933],{"class":186},"            \"Queue\"",[133,935,274],{"class":143},[133,937,938],{"class":186},"\"IT-Support\"",[133,940,190],{"class":143},[133,942,943,946,948,951],{"class":135,"line":412},[133,944,945],{"class":186},"            \"State\"",[133,947,274],{"class":143},[133,949,950],{"class":186},"\"new\"",[133,952,190],{"class":143},[133,954,955,958,960,963],{"class":135,"line":423},[133,956,957],{"class":186},"            \"Priority\"",[133,959,274],{"class":143},[133,961,962],{"class":186},"\"3 normal\"",[133,964,190],{"class":143},[133,966,967,970,972],{"class":135,"line":429},[133,968,969],{"class":186},"            \"CustomerUser\"",[133,971,274],{"class":143},[133,973,974],{"class":186},"\"monitoring\"\n",[133,976,978],{"class":135,"line":977},24,[133,979,980],{"class":143},"        },\n",[133,982,984,987],{"class":135,"line":983},25,[133,985,986],{"class":186},"        \"Article\"",[133,988,364],{"class":143},[133,990,992,995,997,1000],{"class":135,"line":991},26,[133,993,994],{"class":186},"            \"Subject\"",[133,996,274],{"class":143},[133,998,999],{"class":186},"\"Automated Alert\"",[133,1001,190],{"class":143},[133,1003,1005,1008,1010,1013],{"class":135,"line":1004},27,[133,1006,1007],{"class":186},"            \"Body\"",[133,1009,274],{"class":143},[133,1011,1012],{"class":186},"\"Alert details...\"",[133,1014,190],{"class":143},[133,1016,1018,1021,1023],{"class":135,"line":1017},28,[133,1019,1020],{"class":186},"            \"ContentType\"",[133,1022,274],{"class":143},[133,1024,1025],{"class":186},"\"text\u002Fplain; charset=utf8\"\n",[133,1027,1029],{"class":135,"line":1028},29,[133,1030,1031],{"class":143},"        }\n",[133,1033,1035],{"class":135,"line":1034},30,[133,1036,426],{"class":143},[133,1038,1040],{"class":135,"line":1039},31,[133,1041,207],{"class":143},[112,1043,1045],{"id":1044},"python-wrappers-for-otoboznuny","Python Wrappers for OTOBO\u002FZnuny",[14,1047,1048],{},"Compared to Zammad, there are fewer mature Python clients. Recommended approaches:",[1050,1051,1052,1061],"ol",{},[710,1053,1054,1057,1058,1060],{},[18,1055,1056],{},"Custom Thin Client:"," 100-200 lines of wrapper code around ",[82,1059,84],{}," for project-specific endpoints",[710,1062,1063,1066],{},[18,1064,1065],{},"Open Ticket AI:"," Framework with a unified ticket model for OTOBO, Znuny, and Zammad",[14,1068,1069],{},[18,1070,705],{},[707,1072,1073,1080],{},[710,1074,1075],{},[713,1076,1079],{"href":1077,"rel":1078},"https:\u002F\u002Fdoc.otobo.org\u002Fmanual\u002Fdeveloper\u002Fstable\u002Fen\u002Fcontent\u002Fwebservices.html",[717],"OTOBO GenericInterface Docs",[710,1081,1082],{},[713,1083,1086],{"href":1084,"rel":1085},"https:\u002F\u002Fdoc.znuny.org\u002Fmanual\u002Fdeveloper\u002F7.0\u002Fen\u002Fhtml\u002Fwebservices.html",[717],"Znuny Developer Docs",[31,1088],{},[34,1090,1092],{"id":1091},"practical-automation-patterns","Practical Automation Patterns",[112,1094,1096],{"id":1095},"pattern-1-monitoring-ticket-inbound","Pattern 1: Monitoring → Ticket (Inbound)",[124,1098,1100],{"className":126,"code":1099,"language":128,"meta":129,"style":129},"def create_ticket_from_alert(alert_data: dict, system: str):\n    \"\"\"Unified interface for Zammad\u002FOTOBO\u002FZnuny\"\"\"\n\n    if system == \"zammad\":\n        return zammad_client.ticket.create({\n            \"title\": alert_data[\"summary\"],\n            \"group\": \"Monitoring\",\n            \"article\": {\"body\": alert_data[\"details\"]}\n        })\n    elif system in [\"otobo\", \"znuny\"]:\n        return otobo_session.post(\n            f\"\u002FTicketConnectorREST\u002FTicket\",\n            json=map_alert_to_otobo(alert_data)\n        )\n",[82,1101,1102,1134,1139,1143,1160,1172,1186,1198,1217,1222,1245,1256,1266,1279],{"__ignoreMap":129},[133,1103,1104,1107,1110,1112,1116,1118,1121,1123,1126,1128,1131],{"class":135,"line":136},[133,1105,1106],{"class":139},"def",[133,1108,1109],{"class":170}," create_ticket_from_alert",[133,1111,249],{"class":143},[133,1113,1115],{"class":1114},"sb9H8","alert_data",[133,1117,274],{"class":143},[133,1119,1120],{"class":166},"dict",[133,1122,21],{"class":143},[133,1124,1125],{"class":1114},"system",[133,1127,274],{"class":143},[133,1129,1130],{"class":166},"str",[133,1132,1133],{"class":143},"):\n",[133,1135,1136],{"class":135,"line":153},[133,1137,1138],{"class":186},"    \"\"\"Unified interface for Zammad\u002FOTOBO\u002FZnuny\"\"\"\n",[133,1140,1141],{"class":135,"line":160},[133,1142,157],{"emptyLinePlaceholder":156},[133,1144,1145,1148,1151,1154,1157],{"class":135,"line":177},[133,1146,1147],{"class":139},"    if",[133,1149,1150],{"class":143}," system ",[133,1152,1153],{"class":166},"==",[133,1155,1156],{"class":186}," \"zammad\"",[133,1158,1159],{"class":143},":\n",[133,1161,1162,1165,1168,1170],{"class":135,"line":193},[133,1163,1164],{"class":139},"        return",[133,1166,1167],{"class":143}," zammad_client.ticket.",[133,1169,313],{"class":170},[133,1171,316],{"class":143},[133,1173,1174,1177,1180,1183],{"class":135,"line":204},[133,1175,1176],{"class":186},"            \"title\"",[133,1178,1179],{"class":143},": alert_data[",[133,1181,1182],{"class":186},"\"summary\"",[133,1184,1185],{"class":143},"],\n",[133,1187,1188,1191,1193,1196],{"class":135,"line":210},[133,1189,1190],{"class":186},"            \"group\"",[133,1192,274],{"class":143},[133,1194,1195],{"class":186},"\"Monitoring\"",[133,1197,190],{"class":143},[133,1199,1200,1203,1206,1209,1211,1214],{"class":135,"line":215},[133,1201,1202],{"class":186},"            \"article\"",[133,1204,1205],{"class":143},": {",[133,1207,1208],{"class":186},"\"body\"",[133,1210,1179],{"class":143},[133,1212,1213],{"class":186},"\"details\"",[133,1215,1216],{"class":143},"]}\n",[133,1218,1219],{"class":135,"line":222},[133,1220,1221],{"class":143},"        })\n",[133,1223,1224,1227,1229,1231,1234,1237,1239,1242],{"class":135,"line":243},[133,1225,1226],{"class":139},"    elif",[133,1228,1150],{"class":143},[133,1230,231],{"class":139},[133,1232,1233],{"class":143}," [",[133,1235,1236],{"class":186},"\"otobo\"",[133,1238,21],{"class":143},[133,1240,1241],{"class":186},"\"znuny\"",[133,1243,1244],{"class":143},"]:\n",[133,1246,1247,1249,1252,1254],{"class":135,"line":292},[133,1248,1164],{"class":139},[133,1250,1251],{"class":143}," otobo_session.",[133,1253,774],{"class":170},[133,1255,174],{"class":143},[133,1257,1258,1261,1264],{"class":135,"line":297},[133,1259,1260],{"class":139},"            f",[133,1262,1263],{"class":186},"\"\u002FTicketConnectorREST\u002FTicket\"",[133,1265,190],{"class":143},[133,1267,1268,1271,1273,1276],{"class":135,"line":303},[133,1269,1270],{"class":180},"            json",[133,1272,167],{"class":166},[133,1274,1275],{"class":170},"map_alert_to_otobo",[133,1277,1278],{"class":143},"(alert_data)\n",[133,1280,1281],{"class":135,"line":319},[133,1282,1283],{"class":143},"        )\n",[112,1285,1287],{"id":1286},"pattern-2-ticket-escalation-outbound","Pattern 2: Ticket Escalation (Outbound)",[124,1289,1291],{"className":126,"code":1290,"language":128,"meta":129,"style":129},"def escalate_stale_tickets(system_client, hours_threshold: int = 24):\n    \"\"\"Finds and escalates tickets without agent activity\"\"\"\n\n    stale_tickets = system_client.search(\n        query=f\"state:open AND last_contact_agent:[* TO now-{hours_threshold}h]\"\n    )\n\n    for ticket in stale_tickets:\n        system_client.update(ticket[\"id\"], {\n            \"priority\": \"high\",\n            \"tags\": [\"auto-escalated\"],\n            \"note\": f\"Automatically escalated after {hours_threshold}h of inactivity\"\n        })\n",[82,1292,1293,1323,1328,1332,1347,1368,1372,1376,1388,1405,1417,1430,1451],{"__ignoreMap":129},[133,1294,1295,1297,1300,1302,1305,1307,1310,1312,1315,1318,1321],{"class":135,"line":136},[133,1296,1106],{"class":139},[133,1298,1299],{"class":170}," escalate_stale_tickets",[133,1301,249],{"class":143},[133,1303,1304],{"class":1114},"system_client",[133,1306,21],{"class":143},[133,1308,1309],{"class":1114},"hours_threshold",[133,1311,274],{"class":143},[133,1313,1314],{"class":166},"int",[133,1316,1317],{"class":166}," =",[133,1319,1320],{"class":258}," 24",[133,1322,1133],{"class":143},[133,1324,1325],{"class":135,"line":153},[133,1326,1327],{"class":186},"    \"\"\"Finds and escalates tickets without agent activity\"\"\"\n",[133,1329,1330],{"class":135,"line":160},[133,1331,157],{"emptyLinePlaceholder":156},[133,1333,1334,1337,1339,1342,1345],{"class":135,"line":177},[133,1335,1336],{"class":143},"    stale_tickets ",[133,1338,167],{"class":166},[133,1340,1341],{"class":143}," system_client.",[133,1343,1344],{"class":170},"search",[133,1346,174],{"class":143},[133,1348,1349,1352,1354,1356,1359,1361,1363,1365],{"class":135,"line":193},[133,1350,1351],{"class":180},"        query",[133,1353,167],{"class":166},[133,1355,252],{"class":139},[133,1357,1358],{"class":186},"\"state:open AND last_contact_agent:[* TO now-",[133,1360,259],{"class":258},[133,1362,1309],{"class":143},[133,1364,271],{"class":258},[133,1366,1367],{"class":186},"h]\"\n",[133,1369,1370],{"class":135,"line":204},[133,1371,700],{"class":143},[133,1373,1374],{"class":135,"line":210},[133,1375,157],{"emptyLinePlaceholder":156},[133,1377,1378,1381,1383,1385],{"class":135,"line":215},[133,1379,1380],{"class":139},"    for",[133,1382,228],{"class":143},[133,1384,231],{"class":139},[133,1386,1387],{"class":143}," stale_tickets:\n",[133,1389,1390,1393,1396,1399,1402],{"class":135,"line":222},[133,1391,1392],{"class":143},"        system_client.",[133,1394,1395],{"class":170},"update",[133,1397,1398],{"class":143},"(ticket[",[133,1400,1401],{"class":186},"\"id\"",[133,1403,1404],{"class":143},"], {\n",[133,1406,1407,1410,1412,1415],{"class":135,"line":243},[133,1408,1409],{"class":186},"            \"priority\"",[133,1411,274],{"class":143},[133,1413,1414],{"class":186},"\"high\"",[133,1416,190],{"class":143},[133,1418,1419,1422,1425,1428],{"class":135,"line":292},[133,1420,1421],{"class":186},"            \"tags\"",[133,1423,1424],{"class":143},": [",[133,1426,1427],{"class":186},"\"auto-escalated\"",[133,1429,1185],{"class":143},[133,1431,1432,1435,1437,1439,1442,1444,1446,1448],{"class":135,"line":297},[133,1433,1434],{"class":186},"            \"note\"",[133,1436,274],{"class":143},[133,1438,252],{"class":139},[133,1440,1441],{"class":186},"\"Automatically escalated after ",[133,1443,259],{"class":258},[133,1445,1309],{"class":143},[133,1447,271],{"class":258},[133,1449,1450],{"class":186},"h of inactivity\"\n",[133,1452,1453],{"class":135,"line":303},[133,1454,1221],{"class":143},[112,1456,1458],{"id":1457},"pattern-3-data-migration-cross-system","Pattern 3: Data Migration (Cross-System)",[124,1460,1462],{"className":126,"code":1461,"language":128,"meta":129,"style":129},"# Zammad → OTOBO Migration\nfor ticket in zammad_client.ticket.all():\n    mapped_ticket = {\n        \"Title\": ticket[\"title\"],\n        \"Queue\": map_queue(ticket[\"group\"]),\n        \"State\": map_state(ticket[\"state\"]),\n        \"CustomerUser\": ticket[\"customer\"]\n    }\n    otobo_client.ticket.create(mapped_ticket)\n",[82,1463,1464,1469,1483,1492,1505,1523,1539,1551,1555],{"__ignoreMap":129},[133,1465,1466],{"class":135,"line":136},[133,1467,1468],{"class":218},"# Zammad → OTOBO Migration\n",[133,1470,1471,1473,1475,1477,1479,1481],{"class":135,"line":153},[133,1472,225],{"class":139},[133,1474,228],{"class":143},[133,1476,231],{"class":139},[133,1478,1167],{"class":143},[133,1480,237],{"class":170},[133,1482,240],{"class":143},[133,1484,1485,1488,1490],{"class":135,"line":160},[133,1486,1487],{"class":143},"    mapped_ticket ",[133,1489,167],{"class":166},[133,1491,478],{"class":143},[133,1493,1494,1497,1500,1503],{"class":135,"line":177},[133,1495,1496],{"class":186},"        \"Title\"",[133,1498,1499],{"class":143},": ticket[",[133,1501,1502],{"class":186},"\"title\"",[133,1504,1185],{"class":143},[133,1506,1507,1510,1512,1515,1517,1520],{"class":135,"line":193},[133,1508,1509],{"class":186},"        \"Queue\"",[133,1511,274],{"class":143},[133,1513,1514],{"class":170},"map_queue",[133,1516,1398],{"class":143},[133,1518,1519],{"class":186},"\"group\"",[133,1521,1522],{"class":143},"]),\n",[133,1524,1525,1528,1530,1533,1535,1537],{"class":135,"line":204},[133,1526,1527],{"class":186},"        \"State\"",[133,1529,274],{"class":143},[133,1531,1532],{"class":170},"map_state",[133,1534,1398],{"class":143},[133,1536,678],{"class":186},[133,1538,1522],{"class":143},[133,1540,1541,1544,1546,1549],{"class":135,"line":210},[133,1542,1543],{"class":186},"        \"CustomerUser\"",[133,1545,1499],{"class":143},[133,1547,1548],{"class":186},"\"customer\"",[133,1550,616],{"class":143},[133,1552,1553],{"class":135,"line":215},[133,1554,426],{"class":143},[133,1556,1557,1560,1562],{"class":135,"line":222},[133,1558,1559],{"class":143},"    otobo_client.ticket.",[133,1561,313],{"class":170},[133,1563,1564],{"class":143},"(mapped_ticket)\n",[31,1566],{},[34,1568,1570],{"id":1569},"error-handling-and-resilience","Error Handling and Resilience",[14,1572,1573],{},"Production automation requires robust error handling:",[124,1575,1577],{"className":126,"code":1576,"language":128,"meta":129,"style":129},"from tenacity import retry, stop_after_attempt, wait_exponential\nimport logging\n\n@retry(\n    stop=stop_after_attempt(3),\n    wait=wait_exponential(multiplier=1, min=4, max=10)\n)\ndef safe_api_call(func, *args, **kwargs):\n    try:\n        return func(*args, **kwargs)\n    except requests.exceptions.HTTPError as e:\n        if e.response.status_code == 429:  # Rate Limit\n            raise  # Trigger retry\n        elif e.response.status_code == 401:\n            logging.error(\"Authentication failed - check API token\")\n            raise\n        else:\n            logging.error(f\"API Error: {e}\")\n            raise\n",[82,1578,1579,1591,1598,1602,1609,1627,1670,1674,1700,1707,1717,1731,1750,1758,1772,1787,1792,1799,1823],{"__ignoreMap":129},[133,1580,1581,1583,1586,1588],{"class":135,"line":136},[133,1582,140],{"class":139},[133,1584,1585],{"class":143}," tenacity ",[133,1587,147],{"class":139},[133,1589,1590],{"class":143}," retry, stop_after_attempt, wait_exponential\n",[133,1592,1593,1595],{"class":135,"line":153},[133,1594,147],{"class":139},[133,1596,1597],{"class":143}," logging\n",[133,1599,1600],{"class":135,"line":160},[133,1601,157],{"emptyLinePlaceholder":156},[133,1603,1604,1607],{"class":135,"line":177},[133,1605,1606],{"class":170},"@retry",[133,1608,174],{"class":143},[133,1610,1611,1614,1616,1619,1621,1624],{"class":135,"line":193},[133,1612,1613],{"class":180},"    stop",[133,1615,167],{"class":166},[133,1617,1618],{"class":170},"stop_after_attempt",[133,1620,249],{"class":143},[133,1622,1623],{"class":258},"3",[133,1625,1626],{"class":143},"),\n",[133,1628,1629,1632,1634,1637,1639,1642,1644,1647,1650,1653,1655,1658,1660,1663,1665,1668],{"class":135,"line":204},[133,1630,1631],{"class":180},"    wait",[133,1633,167],{"class":166},[133,1635,1636],{"class":170},"wait_exponential",[133,1638,249],{"class":143},[133,1640,1641],{"class":180},"multiplier",[133,1643,167],{"class":166},[133,1645,1646],{"class":258},"1",[133,1648,1649],{"class":143},",",[133,1651,1652],{"class":180}," min",[133,1654,167],{"class":166},[133,1656,1657],{"class":258},"4",[133,1659,1649],{"class":143},[133,1661,1662],{"class":180}," max",[133,1664,167],{"class":166},[133,1666,1667],{"class":258},"10",[133,1669,207],{"class":143},[133,1671,1672],{"class":135,"line":210},[133,1673,207],{"class":143},[133,1675,1676,1678,1681,1683,1686,1689,1692,1695,1698],{"class":135,"line":215},[133,1677,1106],{"class":139},[133,1679,1680],{"class":170}," safe_api_call",[133,1682,249],{"class":143},[133,1684,1685],{"class":1114},"func",[133,1687,1688],{"class":143},", *",[133,1690,1691],{"class":1114},"args",[133,1693,1694],{"class":143},", **",[133,1696,1697],{"class":1114},"kwargs",[133,1699,1133],{"class":143},[133,1701,1702,1705],{"class":135,"line":222},[133,1703,1704],{"class":139},"    try",[133,1706,1159],{"class":143},[133,1708,1709,1711,1714],{"class":135,"line":243},[133,1710,1164],{"class":139},[133,1712,1713],{"class":170}," func",[133,1715,1716],{"class":143},"(*args, **kwargs)\n",[133,1718,1719,1722,1725,1728],{"class":135,"line":292},[133,1720,1721],{"class":139},"    except",[133,1723,1724],{"class":143}," requests.exceptions.HTTPError ",[133,1726,1727],{"class":139},"as",[133,1729,1730],{"class":143}," e:\n",[133,1732,1733,1736,1739,1741,1744,1747],{"class":135,"line":297},[133,1734,1735],{"class":139},"        if",[133,1737,1738],{"class":143}," e.response.status_code ",[133,1740,1153],{"class":166},[133,1742,1743],{"class":258}," 429",[133,1745,1746],{"class":143},":  ",[133,1748,1749],{"class":218},"# Rate Limit\n",[133,1751,1752,1755],{"class":135,"line":303},[133,1753,1754],{"class":139},"            raise",[133,1756,1757],{"class":218},"  # Trigger retry\n",[133,1759,1760,1763,1765,1767,1770],{"class":135,"line":319},[133,1761,1762],{"class":139},"        elif",[133,1764,1738],{"class":143},[133,1766,1153],{"class":166},[133,1768,1769],{"class":258}," 401",[133,1771,1159],{"class":143},[133,1773,1774,1777,1780,1782,1785],{"class":135,"line":332},[133,1775,1776],{"class":143},"            logging.",[133,1778,1779],{"class":170},"error",[133,1781,249],{"class":143},[133,1783,1784],{"class":186},"\"Authentication failed - check API token\"",[133,1786,207],{"class":143},[133,1788,1789],{"class":135,"line":345},[133,1790,1791],{"class":139},"            raise\n",[133,1793,1794,1797],{"class":135,"line":358},[133,1795,1796],{"class":139},"        else",[133,1798,1159],{"class":143},[133,1800,1801,1803,1805,1807,1809,1812,1814,1817,1819,1821],{"class":135,"line":367},[133,1802,1776],{"class":143},[133,1804,1779],{"class":170},[133,1806,249],{"class":143},[133,1808,252],{"class":139},[133,1810,1811],{"class":186},"\"API Error: ",[133,1813,259],{"class":258},[133,1815,1816],{"class":143},"e",[133,1818,271],{"class":258},[133,1820,255],{"class":186},[133,1822,207],{"class":143},[133,1824,1825],{"class":135,"line":380},[133,1826,1791],{"class":139},[31,1828],{},[34,1830,1832],{"id":1831},"gdpr-aspects-in-api-automation","GDPR Aspects in API Automation",[14,1834,1835],{},"Consider the following when accessing ticket data programmatically:",[39,1837,1838,1848],{},[42,1839,1840],{},[45,1841,1842,1845],{},[48,1843,1844],{},"Aspect",[48,1846,1847],{},"Recommendation",[58,1849,1850,1860,1870,1880,1890],{},[45,1851,1852,1857],{},[63,1853,1854],{},[18,1855,1856],{},"API Token Storage",[63,1858,1859],{},"Environment variables or secret manager, never in code",[45,1861,1862,1867],{},[63,1863,1864],{},[18,1865,1866],{},"Logging",[63,1868,1869],{},"Do not store PII (Personally Identifiable Information) in logs",[45,1871,1872,1877],{},[63,1873,1874],{},[18,1875,1876],{},"Access Rights",[63,1878,1879],{},"Service accounts with minimal privileges (Least Privilege)",[45,1881,1882,1887],{},[63,1883,1884],{},[18,1885,1886],{},"Rate Limiting",[63,1888,1889],{},"Respect limits to avoid overloading the system",[45,1891,1892,1897],{},[63,1893,1894],{},[18,1895,1896],{},"Pseudonymization",[63,1898,1899],{},"When forwarding to external systems (e.g., AI APIs)",[31,1901],{},[34,1903,1905],{"id":1904},"comparison-which-system-when","Comparison: Which System When?",[39,1907,1908,1921],{},[42,1909,1910],{},[45,1911,1912,1915,1918],{},[48,1913,1914],{},"Use Case",[48,1916,1917],{},"Recommended Approach",[48,1919,1920],{},"Note",[58,1922,1923,1936,1950,1961,1974],{},[45,1924,1925,1928,1933],{},[63,1926,1927],{},"New Python project, Zammad",[63,1929,1930,1932],{},[82,1931,121],{}," + REST as fallback",[63,1934,1935],{},"Community client covers 80%",[45,1937,1938,1941,1947],{},[63,1939,1940],{},"OTOBO\u002FZnuny integration",[63,1942,1943,1944,1946],{},"Custom ",[82,1945,84],{}," wrapper",[63,1948,1949],{},"Use GenericInterface docs",[45,1951,1952,1955,1958],{},[63,1953,1954],{},"Multi-system automation",[63,1956,1957],{},"Open Ticket AI Framework",[63,1959,1960],{},"Unified data model",[45,1962,1963,1966,1971],{},[63,1964,1965],{},"Prototyping\u002FQuick tests",[63,1967,1968,1969],{},"Jupyter Notebook + ",[82,1970,84],{},[63,1972,1973],{},"Direct API exploration",[45,1975,1976,1979,1986],{},[63,1977,1978],{},"Production cron jobs",[63,1980,1981,1982,1985],{},"Python script + ",[82,1983,1984],{},"python-dotenv"," + logging",[63,1987,1988],{},"Robustness over elegance",[31,1990],{},[34,1992,1994],{"id":1993},"conclusion-and-next-steps","Conclusion and Next Steps",[14,1996,1997,1998],{},"Python automation for ticketing systems is not an either-or choice between client libraries and direct REST usage. Most teams benefit from a ",[18,1999,2000],{},"hybrid approach:",[1050,2002,2003,2009,2015],{},[710,2004,2005,2008],{},[18,2006,2007],{},"Official\u002Fcommunity libraries"," for standard operations",[710,2010,2011,2014],{},[18,2012,2013],{},"Direct REST calls"," for edge cases and debugging",[710,2016,2017,2020],{},[18,2018,2019],{},"Custom abstraction layer"," for cross-system consistency",[14,2022,2023,2024,2028],{},"If you want to dive deeper, check out our ",[713,2025,2027],{"href":2026},"\u002Fzammad-plugins","plugin directories"," for Zammad, OTOBO, and Znuny to find matching extensions that often include built-in Python integrations.",[31,2030],{},[14,2032,2033],{},[2034,2035,2036],"em",{},"This article is a practical technical summary. Please consult the respective official documentation for current API versions and breaking changes.",[2038,2039,2040],"style",{},"html pre.shiki code .seHd6, html code.shiki .seHd6{--shiki-default:#C678DD}html pre.shiki code .sn6KH, html code.shiki .sn6KH{--shiki-default:#ABB2BF}html pre.shiki code .sjrmR, html code.shiki .sjrmR{--shiki-default:#56B6C2}html pre.shiki code .sVbv2, html code.shiki .sVbv2{--shiki-default:#61AFEF}html pre.shiki code .s_ZVi, html code.shiki .s_ZVi{--shiki-default:#E06C75;--shiki-default-font-style:italic}html pre.shiki code .subq3, html code.shiki .subq3{--shiki-default:#98C379}html pre.shiki code .sV9Aq, html code.shiki .sV9Aq{--shiki-default:#7F848E;--shiki-default-font-style:italic}html pre.shiki code .sVC51, html code.shiki .sVC51{--shiki-default:#D19A66}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 pre.shiki code .sb9H8, html code.shiki .sb9H8{--shiki-default:#D19A66;--shiki-default-font-style:italic}",{"title":129,"searchDepth":153,"depth":153,"links":2042},[2043,2044,2049,2053,2058,2059,2060,2061],{"id":36,"depth":153,"text":37},{"id":109,"depth":153,"text":110,"children":2045},[2046,2047],{"id":114,"depth":160,"text":115},{"id":447,"depth":160,"text":2048},"Direct REST API with requests",{"id":730,"depth":153,"text":731,"children":2050},[2051,2052],{"id":741,"depth":160,"text":742},{"id":1044,"depth":160,"text":1045},{"id":1091,"depth":153,"text":1092,"children":2054},[2055,2056,2057],{"id":1095,"depth":160,"text":1096},{"id":1286,"depth":160,"text":1287},{"id":1457,"depth":160,"text":1458},{"id":1569,"depth":153,"text":1570},{"id":1831,"depth":153,"text":1832},{"id":1904,"depth":153,"text":1905},{"id":1993,"depth":153,"text":1994},"2026-05-20","Overview of Python clients and REST API integrations for Zammad, OTOBO, and Znuny—from official libraries to custom automation scripts.",false,"md",{"language":2067},"en","\u002Fblog\u002Fpython-automation-ticketsysteme-rest-api",{"title":5,"description":2063},"blog\u002Fpython-automation-ticketsysteme-rest-api","BNsvf3Lux7JDCOJWPyZ8es1rQ8I04A_ec1IxgksHI_4",1787732994329]