[{"data":1,"prerenderedAt":719},["ShallowReactive",2],{"docs-zammad-plugin-entwickeln-en":3},{"id":4,"title":5,"body":6,"category":709,"description":710,"draft":711,"extension":712,"meta":713,"navigation":386,"order":714,"path":715,"seo":716,"stem":717,"__hash__":718},"docsEn\u002Fdocs\u002Fzammad-plugin-entwickeln.md","Build your own Zammad plugin",{"type":7,"value":8,"toc":695},"minimark",[9,13,38,41,46,140,146,150,157,205,216,223,227,234,283,297,310,314,326,331,338,411,414,418,521,536,540,547,567,570,574,586,597,606,610,632,636,648,652,691],[10,11,5],"h1",{"id":12},"build-your-own-zammad-plugin",[14,15,16,17,21,22,26,27,30,31,34,35,37],"p",{},"Searches for ",[18,19,20],"strong",{},"Zammad plugins"," often assume a marketplace like OTOBO or Znuny (",[23,24,25],"code",{},".opm","). Zammad ",[18,28,29],{},"does not"," ship one. In practice a “custom plugin” is an ",[18,32,33],{},"integration",": you extend the helpdesk through admin features, webhooks, the REST API, or an external app — you do not install an ",[23,36,25],{}," file.",[14,39,40],{},"This guide helps you pick the right path and ship something maintainable.",[42,43,45],"h2",{"id":44},"four-paths-decision-table","Four paths (decision table)",[47,48,49,70],"table",{},[50,51,52],"thead",{},[53,54,55,60,63,67],"tr",{},[56,57,59],"th",{"align":58},"left","Path",[56,61,62],{"align":58},"When it fits",[56,64,66],{"align":65},"center","Upgrade risk",[56,68,69],{"align":58},"Typical result",[71,72,73,90,105,124],"tbody",{},[53,74,75,81,84,87],{},[76,77,78],"td",{"align":58},[18,79,80],{},"Native integration",[76,82,83],{"align":58},"Slack, GitHub, GitLab, Teams, LDAP, CTI, Checkmk … already in core",[76,85,86],{"align":65},"low",[76,88,89],{"align":58},"Configure under Admin → Integrations",[53,91,92,97,100,102],{},[76,93,94],{"align":58},[18,95,96],{},"No-code in Zammad",[76,98,99],{"align":58},"Ticket-flow automation without another product",[76,101,86],{"align":65},[76,103,104],{"align":58},"Triggers, schedulers, webhooks, core workflows, object manager",[53,106,107,112,115,118],{},[76,108,109],{"align":58},[18,110,111],{},"External app \u002F API",[76,113,114],{"align":58},"Portal, ERP, n8n, MCP, monitoring, CMS",[76,116,117],{"align":65},"low–medium",[76,119,120,121],{"align":58},"A service that talks to ",[23,122,123],{},"\u002Fapi\u002Fv1",[53,125,126,131,134,137],{},[76,127,128],{"align":58},[18,129,130],{},"Core patch \u002F fork",[76,132,133],{"align":58},"UI or kernel behavior APIs and triggers cannot cover",[76,135,136],{"align":65},"high",[76,138,139],{"align":58},"Avoid unless you own the release process",[14,141,142,145],{},[18,143,144],{},"Rule of thumb:"," try native and no-code first, then a thin API app. Fork the Zammad core only if you can carry merges, tests, and upgrades.",[42,147,149],{"id":148},"path-1-use-native-integrations","Path 1: Use native integrations",[14,151,152,153,156],{},"Many “Zammad Slack plugin” or “Zammad GitHub plugin” queries are already ",[18,154,155],{},"built in",". Typical modules (see official admin docs):",[158,159,160,181,187,193,199],"ul",{},[161,162,163,166,167,174,175,180],"li",{},[18,164,165],{},"Engineering:"," ",[168,169,173],"a",{"href":170,"rel":171},"https:\u002F\u002Fadmin-docs.zammad.org\u002Fen\u002Flatest\u002Fsystem\u002Fintegrations\u002Fgithub.html",[172],"nofollow","GitHub",", ",[168,176,179],{"href":177,"rel":178},"https:\u002F\u002Fadmin-docs.zammad.org\u002Fen\u002Flatest\u002Fsystem\u002Fintegrations\u002Fgitlab.html",[172],"GitLab"," — show issues on the ticket (GitLab: no merge requests)",[161,182,183,186],{},[18,184,185],{},"Comms:"," Slack, Microsoft Teams, Telegram, SMS, social",[161,188,189,192],{},[18,190,191],{},"Identity & sync:"," LDAP\u002FActive Directory, Microsoft 365, Google, Exchange, Clearbit",[161,194,195,198],{},[18,196,197],{},"Telephony:"," generic CTI, Placetel, Sipgate",[161,200,201,204],{},[18,202,203],{},"Monitoring:"," Checkmk, Icinga, Nagios, Monit",[14,206,207,208,211,212,215],{},"Enable them under ",[18,209,210],{},"Admin → Integrations"," (",[23,213,214],{},"admin.integration"," permission). Test on staging first; issue tokens with least privilege.",[14,217,218,219,222],{},"Directory of community and API packages: ",[168,220,20],{"href":221},"\u002Fzammad-plugins",".",[42,224,226],{"id":225},"path-2-webhooks-triggers-and-the-object-manager","Path 2: Webhooks, triggers, and the object manager",[14,228,229,230,233],{},"If your “plugin” should notify another system on ticket changes, you usually ",[18,231,232],{},"do not"," need Ruby.",[235,236,237,244,255],"ol",{},[161,238,239,240,243],{},"Create an endpoint under ",[18,241,242],{},"Admin → Webhooks"," (generic or a template for Slack, Teams, Mattermost, Rocket.Chat, ntfy).",[161,245,246,247,250,251,254],{},"Configure a ",[18,248,249],{},"trigger"," or ",[18,252,253],{},"scheduler"," to invoke that webhook.",[161,256,257,258],{},"On the receiver, inspect:\n",[158,259,260,266,272,278],{},[161,261,262,265],{},[23,263,264],{},"X-Zammad-Trigger"," — trigger name",[161,267,268,271],{},[23,269,270],{},"X-Zammad-Delivery"," — unique delivery id (idempotency)",[161,273,274,277],{},[23,275,276],{},"X-Hub-Signature"," — HMAC-SHA1 if you set a signature token",[161,279,280],{},[23,281,282],{},"User-Agent: Zammad User Agent",[14,284,285,288,289,292,293,296],{},[18,286,287],{},"Core workflows"," cover conditional fields and visibility. The ",[18,290,291],{},"object manager"," (UI or ",[23,294,295],{},"POST \u002Fapi\u002Fv1\u002Fobject",") adds custom fields on ticket, user, or organization — often enough for domain data without core code.",[14,298,299,300,174,305,222],{},"Official starters: ",[168,301,304],{"href":302,"rel":303},"https:\u002F\u002Fadmin-docs.zammad.org\u002Fen\u002Flatest\u002Fmanage\u002Fwebhook\u002Fadd.html",[172],"Add webhooks",[168,306,309],{"href":307,"rel":308},"https:\u002F\u002Fadmin-docs.zammad.org\u002Fen\u002Flatest\u002Fmanage\u002Fwebhook\u002Fpayload.html",[172],"Webhook payload",[42,311,313],{"id":312},"path-3-your-plugin-as-a-rest-api-integration","Path 3: Your plugin as a REST API integration",[14,315,316,317,320,321,222],{},"This is the default for a ",[18,318,319],{},"custom Zammad plugin",": a service (Python, Node, PHP, n8n, MCP) that uses the ",[168,322,325],{"href":323,"rel":324},"https:\u002F\u002Fdocs.zammad.org\u002Fen\u002Flatest\u002Fapi\u002Fintro.html",[172],"Zammad REST API",[327,328,330],"h3",{"id":329},"authentication","Authentication",[14,332,333,334,337],{},"Zammad supports three methods. Prefer ",[18,335,336],{},"access tokens"," for integrations; avoid basic auth.",[339,340,345],"pre",{"className":341,"code":342,"language":343,"meta":344,"style":344},"language-bash shiki shiki-themes one-dark-pro","# HTTP token (recommended)\ncurl -H \"Authorization: Token token=YOUR_TOKEN\" \\\n  https:\u002F\u002Fhelpdesk.example.com\u002Fapi\u002Fv1\u002Fusers\u002Fme\n\n# OAuth2 bearer\ncurl -H \"Authorization: Bearer YOUR_TOKEN\" \\\n  https:\u002F\u002Fhelpdesk.example.com\u002Fapi\u002Fv1\u002Fusers\u002Fme\n","bash","",[23,346,347,356,375,381,388,394,406],{"__ignoreMap":344},[348,349,352],"span",{"class":350,"line":351},"line",1,[348,353,355],{"class":354},"sV9Aq","# HTTP token (recommended)\n",[348,357,359,363,367,371],{"class":350,"line":358},2,[348,360,362],{"class":361},"sVbv2","curl",[348,364,366],{"class":365},"sVC51"," -H",[348,368,370],{"class":369},"subq3"," \"Authorization: Token token=YOUR_TOKEN\"",[348,372,374],{"class":373},"sjrmR"," \\\n",[348,376,378],{"class":350,"line":377},3,[348,379,380],{"class":369},"  https:\u002F\u002Fhelpdesk.example.com\u002Fapi\u002Fv1\u002Fusers\u002Fme\n",[348,382,384],{"class":350,"line":383},4,[348,385,387],{"emptyLinePlaceholder":386},true,"\n",[348,389,391],{"class":350,"line":390},5,[348,392,393],{"class":354},"# OAuth2 bearer\n",[348,395,397,399,401,404],{"class":350,"line":396},6,[348,398,362],{"class":361},[348,400,366],{"class":365},[348,402,403],{"class":369}," \"Authorization: Bearer YOUR_TOKEN\"",[348,405,374],{"class":373},[348,407,409],{"class":350,"line":408},7,[348,410,380],{"class":369},[14,412,413],{},"Users create tokens in personal preferences. Scope permissions as tightly as possible.",[327,415,417],{"id":416},"create-a-ticket-example","Create a ticket (example)",[339,419,421],{"className":341,"code":420,"language":343,"meta":344,"style":344},"curl -X POST https:\u002F\u002Fhelpdesk.example.com\u002Fapi\u002Fv1\u002Ftickets \\\n  -H \"Authorization: Token token=YOUR_TOKEN\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"title\": \"Monitoring: CPU > 90%\",\n    \"group\": \"Users\",\n    \"customer\": \"monitoring@example.com\",\n    \"article\": {\n      \"subject\": \"Alert\",\n      \"body\": \"Host server-01 exceeded the threshold.\",\n      \"type\": \"note\",\n      \"internal\": true\n    }\n  }'\n",[23,422,423,438,447,456,464,469,474,479,485,491,497,503,509,515],{"__ignoreMap":344},[348,424,425,427,430,433,436],{"class":350,"line":351},[348,426,362],{"class":361},[348,428,429],{"class":365}," -X",[348,431,432],{"class":369}," POST",[348,434,435],{"class":369}," https:\u002F\u002Fhelpdesk.example.com\u002Fapi\u002Fv1\u002Ftickets",[348,437,374],{"class":373},[348,439,440,443,445],{"class":350,"line":358},[348,441,442],{"class":365},"  -H",[348,444,370],{"class":369},[348,446,374],{"class":373},[348,448,449,451,454],{"class":350,"line":377},[348,450,442],{"class":365},[348,452,453],{"class":369}," \"Content-Type: application\u002Fjson\"",[348,455,374],{"class":373},[348,457,458,461],{"class":350,"line":383},[348,459,460],{"class":365},"  -d",[348,462,463],{"class":369}," '{\n",[348,465,466],{"class":350,"line":390},[348,467,468],{"class":369},"    \"title\": \"Monitoring: CPU > 90%\",\n",[348,470,471],{"class":350,"line":396},[348,472,473],{"class":369},"    \"group\": \"Users\",\n",[348,475,476],{"class":350,"line":408},[348,477,478],{"class":369},"    \"customer\": \"monitoring@example.com\",\n",[348,480,482],{"class":350,"line":481},8,[348,483,484],{"class":369},"    \"article\": {\n",[348,486,488],{"class":350,"line":487},9,[348,489,490],{"class":369},"      \"subject\": \"Alert\",\n",[348,492,494],{"class":350,"line":493},10,[348,495,496],{"class":369},"      \"body\": \"Host server-01 exceeded the threshold.\",\n",[348,498,500],{"class":350,"line":499},11,[348,501,502],{"class":369},"      \"type\": \"note\",\n",[348,504,506],{"class":350,"line":505},12,[348,507,508],{"class":369},"      \"internal\": true\n",[348,510,512],{"class":350,"line":511},13,[348,513,514],{"class":369},"    }\n",[348,516,518],{"class":350,"line":517},14,[348,519,520],{"class":369},"  }'\n",[14,522,523,524,174,528,174,532,222],{},"The same pattern fits portals, checkout, forms, or monitoring callbacks. Ready-made clients in the hub: ",[168,525,527],{"href":526},"\u002Fpackages\u002Fzammadpy","zammad_py",[168,529,531],{"href":530},"\u002Fpackages\u002Fzammad-api-client-php","zammad-api-client-php",[168,533,535],{"href":534},"\u002Fpackages\u002Flaravel-zammad","laravel-zammad",[327,537,539],{"id":538},"automation-layer-instead-of-a-core-plugin","Automation layer instead of a core plugin",[14,541,542,543,546],{},"If you orchestrate workflows (ERP ↔ Zammad, Entra ID sync, AI drafts), keep logic ",[18,544,545],{},"outside"," Zammad:",[158,548,549,560],{},[161,550,551,555,556],{},[168,552,554],{"href":553},"\u002Fpackages\u002Fdigital-bossn8n-nodes-zammad","n8n-nodes-zammad"," \u002F ",[168,557,559],{"href":558},"\u002Fpackages\u002Fn8n-nodes-zammad-extended","n8n-nodes-zammad-extended",[161,561,562,566],{},[168,563,565],{"href":564},"\u002Fpackages\u002Fzammad-mcp-server","zammad-mcp-server"," for agents in Claude, Cursor, and similar tools",[14,568,569],{},"Zammad upgrades then stay independent of your plugin logic.",[42,571,573],{"id":572},"path-4-changing-the-zammad-core","Path 4: Changing the Zammad core",[14,575,576,577,581,582,585],{},"Zammad is AGPL-3.0 (Ruby on Rails, modern Vue frontend). You ",[578,579,580],"em",{},"can"," fork the source. That is ",[18,583,584],{},"not"," a plugin marketplace:",[158,587,588,591,594],{},[161,589,590],{},"Every upgrade must re-merge your patches.",[161,592,593],{},"Frontend and API contracts change across majors (for example Zammad 6 → 7).",[161,595,596],{},"Hosted offerings (Zammad Cloud) typically reject kernel patches.",[14,598,599,600,605],{},"To contribute upstream, follow the ",[168,601,604],{"href":602,"rel":603},"https:\u002F\u002Fdocs.zammad.org\u002Fen\u002Flatest\u002Fcontributing\u002Fstart.html",[172],"official contributing docs"," — that is core development, not a private add-on format.",[42,607,609],{"id":608},"go-live-checklist","Go-live checklist",[158,611,612,615,618,623,626,629],{},[161,613,614],{},"Staging instance with a production-like data model",[161,616,617],{},"Least-privilege tokens and documented rotation",[161,619,620,621],{},"Verify webhook signatures; handle retries and ",[23,622,270],{},[161,624,625],{},"Personal ticket data: processing agreements, storage location, logs",[161,627,628],{},"Re-test after Zammad minor updates (API fields, integrations)",[161,630,631],{},"README: required Zammad version, permissions, sample payloads",[42,633,635],{"id":634},"list-it-on-open-itsm-hub","List it on Open ITSM Hub",[14,637,638,639,643,644,222],{},"Community integrations often live only as GitHub repos. Add your project to the ",[168,640,642],{"href":641},"\u002Fpackages","package directory"," so admins can find “Zammad plugins” in one place. For OTOBO\u002FZnuny packages see ",[168,645,647],{"href":646},"\u002Fdocs\u002Fpaket-veroeffentlichen","Publish a package",[42,649,651],{"id":650},"further-reading","Further reading",[158,653,654,660,666,672,678],{},[161,655,656],{},[168,657,659],{"href":658},"\u002Fblog\u002Fbeste-zammad-plugins-2026","Best Zammad plugins 2026",[161,661,662],{},[168,663,665],{"href":664},"\u002Fblog\u002Fzammad-plugin-selber-bauen","Build a Zammad plugin (overview)",[161,667,668],{},[168,669,671],{"href":670},"\u002Fblog\u002Fzammad-mcp-server-vergleich","Zammad MCP server comparison",[161,673,674],{},[168,675,677],{"href":676},"\u002Fblog\u002Fpython-automation-ticketsysteme-rest-api","Python automation for ticketing systems",[161,679,680,681,685,686],{},"Official: ",[168,682,684],{"href":323,"rel":683},[172],"API intro"," · ",[168,687,690],{"href":688,"rel":689},"https:\u002F\u002Fadmin-docs.zammad.org\u002Fen\u002Flatest\u002Fsystem\u002Fintegrations\u002Findex.html",[172],"Integrations",[692,693,694],"style",{},"html pre.shiki code .sV9Aq, html code.shiki .sV9Aq{--shiki-default:#7F848E;--shiki-default-font-style:italic}html pre.shiki code .sVbv2, html code.shiki .sVbv2{--shiki-default:#61AFEF}html pre.shiki code .sVC51, html code.shiki .sVC51{--shiki-default:#D19A66}html pre.shiki code .subq3, html code.shiki .subq3{--shiki-default:#98C379}html pre.shiki code .sjrmR, html code.shiki .sjrmR{--shiki-default:#56B6C2}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);}",{"title":344,"searchDepth":358,"depth":358,"links":696},[697,698,699,700,705,706,707,708],{"id":44,"depth":358,"text":45},{"id":148,"depth":358,"text":149},{"id":225,"depth":358,"text":226},{"id":312,"depth":358,"text":313,"children":701},[702,703,704],{"id":329,"depth":377,"text":330},{"id":416,"depth":377,"text":417},{"id":538,"depth":377,"text":539},{"id":572,"depth":358,"text":573},{"id":608,"depth":358,"text":609},{"id":634,"depth":358,"text":635},{"id":650,"depth":358,"text":651},"Zammad","How to create a Zammad plugin or custom integration: native integrations, webhooks, REST API, n8n, and the limits of Zammad’s add-on model.",false,"md",{},70,"\u002Fdocs\u002Fzammad-plugin-entwickeln",{"title":5,"description":710},"docs\u002Fzammad-plugin-entwickeln","4d95H45aOrLtRneUB414yaTJYUN00KI5yjkHMYEFyS8",1793464859156]