[{"data":1,"prerenderedAt":1748},["ShallowReactive",2],{"search-de":3,"content-de-developer\u002Fplugin-send-providers":4,"surround-de-\u002Fdeveloper\u002Fplugin-send-providers":1739},[],{"id":5,"title":6,"body":7,"description":1732,"extension":1733,"meta":1734,"navigation":276,"path":1735,"seo":1736,"stem":1737,"__hash__":1738},"content_de\u002F3.developer\u002F49.plugin-send-providers.md","Einen Send-Provider schreiben",{"type":8,"value":9,"toc":1720},"minimark",[10,24,31,34,76,83,114,119,189,213,245,873,892,896,907,919,1052,1059,1086,1090,1093,1279,1284,1316,1335,1341,1345,1382,1386,1393,1426,1436,1475,1486,1489,1496,1511,1514,1518,1535,1661,1664,1668,1716],[11,12,13,14,18,19,23],"p",{},"Ein ",[15,16,17],"strong",{},"Send-Provider"," ist ein Versandanbieter, der nicht Owlats eigener MTA ist: ein ESP, ein Relay, ein SMTP-Dienst. Owlat behandelt jeden von ihnen als ",[20,21,22],"em",{},"Bundle"," — ein Sendepfad, ein Feedback-Pfad, eine Sending-Domain-Identität, Capability-Deklarationen und ein Formular für Zugangsdaten, die zusammen reisen — und nimmt dieses Bundle auf jeder der zwei Stufen mit demselben Vertrag entgegen.",[11,25,26,27,30],{},"Provider N+1 ist ein ",[15,28,29],{},"Package",". Weder Routing, Dispatch, Retries, der Deliverability-Fallback, der Ramp-Controller, die Measurement-Ebene noch die UI für Zugangsdaten werden bearbeitet, um einen hinzuzufügen.",[11,32,33],{},"Beginnen Sie mit dem Scaffold:",[35,36,41],"pre",{"className":37,"code":38,"language":39,"meta":40,"style":40},"language-sh shiki shiki-themes github-light github-dark-dimmed","owlat plugins create acme-relay --name @acme\u002Fowlat-relay --template send-provider\n","sh","",[42,43,44],"code",{"__ignoreMap":40},[45,46,49,53,57,60,63,67,70,73],"span",{"class":47,"line":48},"line",1,[45,50,52],{"class":51},"sOLd2","owlat",[45,54,56],{"class":55},"s-HuK"," plugins",[45,58,59],{"class":55}," create",[45,61,62],{"class":55}," acme-relay",[45,64,66],{"class":65},"sviXB"," --name",[45,68,69],{"class":55}," @acme\u002Fowlat-relay",[45,71,72],{"class":65}," --template",[45,74,75],{"class":55}," send-provider\n",[11,77,78,79,82],{},"Das erzeugt ein vollständiges, komponierendes Bundle: alle drei ausführbaren Hälften, jedes Capability-Feld, das diese Stufe deklarieren darf, ein Formular für Zugangsdaten, das mit den von ihm geschriebenen Variablen verbunden ist, einen host-verifizierbaren Webhook-Vertrag sowie eine Testsuite je Hälfte. Übrig bleibt der Anteil Ihres Anbieters, an genau der Zeile mit ",[42,80,81],{},"TODO"," markiert, an die er gehört.",[11,84,85,86,89,90,93,94,97,98,101,102,105,106,109,110,113],{},"Das Scaffold landet ",[20,87,88],{},"innerhalb"," des Owlat-Checkouts, in dem Sie es ausführen — ",[42,91,92],{},"examples\u002Fplugins\u002F\u003Cid>",", sofern Sie kein ",[42,95,96],{},"--dir"," übergeben, und niemals außerhalb des Workspace. Deshalb ist die erzeugte ",[42,99,100],{},"package.json"," ",[42,103,104],{},"private"," und ihre Dependencies sind ",[42,107,108],{},"workspace:*","- und ",[42,111,112],{},"catalog:","-Spezifikatoren: Das Package ist an diesen Checkout gebunden, bis Sie es herauslösen. Das Veröffentlichen ist der letzte Schritt dieses Herauslösens, und die erzeugte README listet die vier Dinge auf, aus denen dieser Schritt besteht.",[115,116,118],"h2",{"id":117},"das-bundle","Das Bundle",[120,121,122,138],"table",{},[123,124,125],"thead",{},[126,127,128,132,135],"tr",{},[129,130,131],"th",{},"Hälfte",[129,133,134],{},"Was sie ist",[129,136,137],{},"Erforderlich",[139,140,141,157,167,178],"tbody",{},[126,142,143,147,154],{},[144,145,146],"td",{},"Katalog-Deklaration",[144,148,149,150,153],{},"Die ",[42,151,152],{},"sendTransports","-Contribution in Ihrem Manifest: Capabilities, Formular für Zugangsdaten, Retry-Verzögerungen",[144,155,156],{},"Immer",[126,158,159,162,165],{},[144,160,161],{},"Send-Modul",[144,163,164],{},"Ein Netzwerkversuch pro Aufruf, der ein typisiertes Ergebnis zurückgibt",[144,166,156],{},[126,168,169,172,175],{},[144,170,171],{},"Feedback-Webhook",[144,173,174],{},"Nur Parsing: verifizierte Bytes hinein, Feedback-Fakten hinaus",[144,176,177],{},"Nur wenn Ihr Provider Zustellereignisse meldet",[126,179,180,183,186],{},[144,181,182],{},"Sending-Domain-Identität",[144,184,185],{},"Die Provider-Konversation über die eigene Domain eines Kunden",[144,187,188],{},"Nur wenn Ihr Provider Domains über eine API verifiziert",[11,190,191,192,101,195,198,199,202,203,101,206,208,209,212],{},"Die beiden optionalen Hälften werden nicht von einem Boolean begleitet. Das Deklarieren eines ",[42,193,194],{},"webhook",[15,196,197],{},"ist"," das ",[42,200,201],{},"hasProviderFeedback: true"," des Katalogs für Ihre Art, und das Deklarieren einer ",[42,204,205],{},"domainIdentity",[15,207,197],{}," dessen ",[42,210,211],{},"domainVerification: 'api'",". Eine Tatsache, einmal ausgesprochen: Ein Boolean daneben könnte nur jemals dem Modul widersprechen, das sie implementiert.",[11,214,215,216,219,220,222,223,228,229,232,233,236,237,240,241,244],{},"Unten steht das Manifest, um das herum ein Bundle gebaut wird — die ",[42,217,218],{},"src\u002Fmanifest.ts"," des Scaffolds mit beantworteten Anbieter-",[42,221,81],{},"s. Sie erweitert die Datei, die das ",[224,225,227],"a",{"href":226},"\u002Fdeveloper\u002Fplugin-authoring","minimale Manifest"," beginnt, importiert also nur die Capability-Konstante, die sie hinzufügt; ",[42,230,231],{},"definePlugin"," ist bereits im Scope. Das Scaffold leitet jeden Variablennamen und Header aus Ihrer Plugin-Id ab (",[42,234,235],{},"acme-relay"," ⇒ ",[42,238,239],{},"PLUGIN_ACME_RELAY_API_KEY",", ",[42,242,243],{},"x-acme-relay-signature","), und genau das sind die Namen hier.",[35,246,250],{"className":247,"code":248,"language":249,"meta":40,"style":40},"language-ts shiki shiki-themes github-light github-dark-dimmed","import { PLUGIN_SEND_TRANSPORT_CAPABILITY } from '@owlat\u002Fplugin-kit';\n\nexport const acmeRelayPlugin = definePlugin({\n    id: 'acme-relay',\n    version: '1.0.0',\n    capabilities: [PLUGIN_SEND_TRANSPORT_CAPABILITY],\n    \u002F\u002F Deployment-wide: the plugin is off until both are set. The signing secret\n    \u002F\u002F belongs HERE and not on the transport — without it the feedback route can\n    \u002F\u002F verify nothing and answers every delivery 503.\n    flag: {\n        default: false,\n        requiredEnvVars: ['ACME_RELAY_ENABLED', 'PLUGIN_ACME_RELAY_WEBHOOK_SECRET'],\n    },\n    contributes: {\n        sendTransports: [\n            {\n                id: 'relay',\n                label: 'Acme Relay',\n                module: { exportPath: '.\u002Fconvex\u002Ftransport' },\n                retryDelays: [1_000, 5_000],\n                \u002F\u002F THIS TRANSPORT's own configuration: resolved per named instance\n                \u002F\u002F (`PLUGIN_ACME_RELAY_API_KEY__EU` for `plugin.acme-relay.relay#eu`) and\n                \u002F\u002F handed to `send` keyed by the base name.\n                requiredEnvVars: ['PLUGIN_ACME_RELAY_API_KEY'],\n                optionalEnvVars: ['PLUGIN_ACME_RELAY_REGION'],\n                credentialFields: [\n                    {\n                        kind: 'secret',\n                        key: 'apiKey',\n                        label: 'API key',\n                        required: true,\n                        envVar: 'PLUGIN_ACME_RELAY_API_KEY',\n                    },\n                    {\n                        kind: 'select',\n                        key: 'region',\n                        label: 'Sending region',\n                        options: [\n                            { value: 'eu', label: 'Europe' },\n                            { value: 'us', label: 'United States' },\n                        ],\n                        default: 'eu',\n                        envVar: 'PLUGIN_ACME_RELAY_REGION',\n                    },\n                ],\n                \u002F\u002F `no` is the only value this tier may declare.\n                supportsCustomReturnPath: 'no',\n                messageIdSource: 'provider',\n                deduplicatesOnIdempotencyKey: false,\n                \u002F\u002F Declaring a webhook IS `hasProviderFeedback: true` for this kind.\n                webhook: {\n                    module: { exportPath: '.\u002Fconvex\u002Fwebhook' },\n                    signature: {\n                        header: 'x-acme-relay-signature',\n                        algorithm: 'hmac-sha256',\n                        encoding: 'hex',\n                        secretEnvVar: 'PLUGIN_ACME_RELAY_WEBHOOK_SECRET',\n                        \u002F\u002F REQUIRED: without replay provisions a captured request verifies\n                        \u002F\u002F forever. The host signs `\u003Ctimestamp>.\u003CrawBody>`.\n                        replay: { timestampHeader: 'x-acme-relay-timestamp', toleranceSeconds: 300 },\n                    },\n                },\n                \u002F\u002F Declaring an identity IS `domainVerification: 'api'` for this kind.\n                domainIdentity: { module: { exportPath: '.\u002Fconvex\u002FdomainIdentity' } },\n            },\n        ],\n    },\n});\n","ts",[42,251,252,271,278,300,312,323,335,342,348,354,360,371,387,393,399,405,411,422,433,445,461,467,473,479,490,501,507,513,524,535,546,557,567,573,578,588,598,608,614,631,646,652,662,671,676,682,688,699,710,720,726,732,743,749,760,771,782,792,798,804,821,826,832,838,850,856,862,867],{"__ignoreMap":40},[45,253,254,258,262,265,268],{"class":47,"line":48},[45,255,257],{"class":256},"s7YZ4","import",[45,259,261],{"class":260},"sYgZi"," { PLUGIN_SEND_TRANSPORT_CAPABILITY } ",[45,263,264],{"class":256},"from",[45,266,267],{"class":55}," '@owlat\u002Fplugin-kit'",[45,269,270],{"class":260},";\n",[45,272,274],{"class":47,"line":273},2,[45,275,277],{"emptyLinePlaceholder":276},true,"\n",[45,279,281,284,287,290,293,297],{"class":47,"line":280},3,[45,282,283],{"class":256},"export",[45,285,286],{"class":256}," const",[45,288,289],{"class":65}," acmeRelayPlugin",[45,291,292],{"class":256}," =",[45,294,296],{"class":295},"sPO5f"," definePlugin",[45,298,299],{"class":260},"({\n",[45,301,303,306,309],{"class":47,"line":302},4,[45,304,305],{"class":260},"    id: ",[45,307,308],{"class":55},"'acme-relay'",[45,310,311],{"class":260},",\n",[45,313,315,318,321],{"class":47,"line":314},5,[45,316,317],{"class":260},"    version: ",[45,319,320],{"class":55},"'1.0.0'",[45,322,311],{"class":260},[45,324,326,329,332],{"class":47,"line":325},6,[45,327,328],{"class":260},"    capabilities: [",[45,330,331],{"class":65},"PLUGIN_SEND_TRANSPORT_CAPABILITY",[45,333,334],{"class":260},"],\n",[45,336,338],{"class":47,"line":337},7,[45,339,341],{"class":340},"sDN9O","    \u002F\u002F Deployment-wide: the plugin is off until both are set. The signing secret\n",[45,343,345],{"class":47,"line":344},8,[45,346,347],{"class":340},"    \u002F\u002F belongs HERE and not on the transport — without it the feedback route can\n",[45,349,351],{"class":47,"line":350},9,[45,352,353],{"class":340},"    \u002F\u002F verify nothing and answers every delivery 503.\n",[45,355,357],{"class":47,"line":356},10,[45,358,359],{"class":260},"    flag: {\n",[45,361,363,366,369],{"class":47,"line":362},11,[45,364,365],{"class":260},"        default: ",[45,367,368],{"class":65},"false",[45,370,311],{"class":260},[45,372,374,377,380,382,385],{"class":47,"line":373},12,[45,375,376],{"class":260},"        requiredEnvVars: [",[45,378,379],{"class":55},"'ACME_RELAY_ENABLED'",[45,381,240],{"class":260},[45,383,384],{"class":55},"'PLUGIN_ACME_RELAY_WEBHOOK_SECRET'",[45,386,334],{"class":260},[45,388,390],{"class":47,"line":389},13,[45,391,392],{"class":260},"    },\n",[45,394,396],{"class":47,"line":395},14,[45,397,398],{"class":260},"    contributes: {\n",[45,400,402],{"class":47,"line":401},15,[45,403,404],{"class":260},"        sendTransports: [\n",[45,406,408],{"class":47,"line":407},16,[45,409,410],{"class":260},"            {\n",[45,412,414,417,420],{"class":47,"line":413},17,[45,415,416],{"class":260},"                id: ",[45,418,419],{"class":55},"'relay'",[45,421,311],{"class":260},[45,423,425,428,431],{"class":47,"line":424},18,[45,426,427],{"class":260},"                label: ",[45,429,430],{"class":55},"'Acme Relay'",[45,432,311],{"class":260},[45,434,436,439,442],{"class":47,"line":435},19,[45,437,438],{"class":260},"                module: { exportPath: ",[45,440,441],{"class":55},"'.\u002Fconvex\u002Ftransport'",[45,443,444],{"class":260}," },\n",[45,446,448,451,454,456,459],{"class":47,"line":447},20,[45,449,450],{"class":260},"                retryDelays: [",[45,452,453],{"class":65},"1_000",[45,455,240],{"class":260},[45,457,458],{"class":65},"5_000",[45,460,334],{"class":260},[45,462,464],{"class":47,"line":463},21,[45,465,466],{"class":340},"                \u002F\u002F THIS TRANSPORT's own configuration: resolved per named instance\n",[45,468,470],{"class":47,"line":469},22,[45,471,472],{"class":340},"                \u002F\u002F (`PLUGIN_ACME_RELAY_API_KEY__EU` for `plugin.acme-relay.relay#eu`) and\n",[45,474,476],{"class":47,"line":475},23,[45,477,478],{"class":340},"                \u002F\u002F handed to `send` keyed by the base name.\n",[45,480,482,485,488],{"class":47,"line":481},24,[45,483,484],{"class":260},"                requiredEnvVars: [",[45,486,487],{"class":55},"'PLUGIN_ACME_RELAY_API_KEY'",[45,489,334],{"class":260},[45,491,493,496,499],{"class":47,"line":492},25,[45,494,495],{"class":260},"                optionalEnvVars: [",[45,497,498],{"class":55},"'PLUGIN_ACME_RELAY_REGION'",[45,500,334],{"class":260},[45,502,504],{"class":47,"line":503},26,[45,505,506],{"class":260},"                credentialFields: [\n",[45,508,510],{"class":47,"line":509},27,[45,511,512],{"class":260},"                    {\n",[45,514,516,519,522],{"class":47,"line":515},28,[45,517,518],{"class":260},"                        kind: ",[45,520,521],{"class":55},"'secret'",[45,523,311],{"class":260},[45,525,527,530,533],{"class":47,"line":526},29,[45,528,529],{"class":260},"                        key: ",[45,531,532],{"class":55},"'apiKey'",[45,534,311],{"class":260},[45,536,538,541,544],{"class":47,"line":537},30,[45,539,540],{"class":260},"                        label: ",[45,542,543],{"class":55},"'API key'",[45,545,311],{"class":260},[45,547,549,552,555],{"class":47,"line":548},31,[45,550,551],{"class":260},"                        required: ",[45,553,554],{"class":65},"true",[45,556,311],{"class":260},[45,558,560,563,565],{"class":47,"line":559},32,[45,561,562],{"class":260},"                        envVar: ",[45,564,487],{"class":55},[45,566,311],{"class":260},[45,568,570],{"class":47,"line":569},33,[45,571,572],{"class":260},"                    },\n",[45,574,576],{"class":47,"line":575},34,[45,577,512],{"class":260},[45,579,581,583,586],{"class":47,"line":580},35,[45,582,518],{"class":260},[45,584,585],{"class":55},"'select'",[45,587,311],{"class":260},[45,589,591,593,596],{"class":47,"line":590},36,[45,592,529],{"class":260},[45,594,595],{"class":55},"'region'",[45,597,311],{"class":260},[45,599,601,603,606],{"class":47,"line":600},37,[45,602,540],{"class":260},[45,604,605],{"class":55},"'Sending region'",[45,607,311],{"class":260},[45,609,611],{"class":47,"line":610},38,[45,612,613],{"class":260},"                        options: [\n",[45,615,617,620,623,626,629],{"class":47,"line":616},39,[45,618,619],{"class":260},"                            { value: ",[45,621,622],{"class":55},"'eu'",[45,624,625],{"class":260},", label: ",[45,627,628],{"class":55},"'Europe'",[45,630,444],{"class":260},[45,632,634,636,639,641,644],{"class":47,"line":633},40,[45,635,619],{"class":260},[45,637,638],{"class":55},"'us'",[45,640,625],{"class":260},[45,642,643],{"class":55},"'United States'",[45,645,444],{"class":260},[45,647,649],{"class":47,"line":648},41,[45,650,651],{"class":260},"                        ],\n",[45,653,655,658,660],{"class":47,"line":654},42,[45,656,657],{"class":260},"                        default: ",[45,659,622],{"class":55},[45,661,311],{"class":260},[45,663,665,667,669],{"class":47,"line":664},43,[45,666,562],{"class":260},[45,668,498],{"class":55},[45,670,311],{"class":260},[45,672,674],{"class":47,"line":673},44,[45,675,572],{"class":260},[45,677,679],{"class":47,"line":678},45,[45,680,681],{"class":260},"                ],\n",[45,683,685],{"class":47,"line":684},46,[45,686,687],{"class":340},"                \u002F\u002F `no` is the only value this tier may declare.\n",[45,689,691,694,697],{"class":47,"line":690},47,[45,692,693],{"class":260},"                supportsCustomReturnPath: ",[45,695,696],{"class":55},"'no'",[45,698,311],{"class":260},[45,700,702,705,708],{"class":47,"line":701},48,[45,703,704],{"class":260},"                messageIdSource: ",[45,706,707],{"class":55},"'provider'",[45,709,311],{"class":260},[45,711,713,716,718],{"class":47,"line":712},49,[45,714,715],{"class":260},"                deduplicatesOnIdempotencyKey: ",[45,717,368],{"class":65},[45,719,311],{"class":260},[45,721,723],{"class":47,"line":722},50,[45,724,725],{"class":340},"                \u002F\u002F Declaring a webhook IS `hasProviderFeedback: true` for this kind.\n",[45,727,729],{"class":47,"line":728},51,[45,730,731],{"class":260},"                webhook: {\n",[45,733,735,738,741],{"class":47,"line":734},52,[45,736,737],{"class":260},"                    module: { exportPath: ",[45,739,740],{"class":55},"'.\u002Fconvex\u002Fwebhook'",[45,742,444],{"class":260},[45,744,746],{"class":47,"line":745},53,[45,747,748],{"class":260},"                    signature: {\n",[45,750,752,755,758],{"class":47,"line":751},54,[45,753,754],{"class":260},"                        header: ",[45,756,757],{"class":55},"'x-acme-relay-signature'",[45,759,311],{"class":260},[45,761,763,766,769],{"class":47,"line":762},55,[45,764,765],{"class":260},"                        algorithm: ",[45,767,768],{"class":55},"'hmac-sha256'",[45,770,311],{"class":260},[45,772,774,777,780],{"class":47,"line":773},56,[45,775,776],{"class":260},"                        encoding: ",[45,778,779],{"class":55},"'hex'",[45,781,311],{"class":260},[45,783,785,788,790],{"class":47,"line":784},57,[45,786,787],{"class":260},"                        secretEnvVar: ",[45,789,384],{"class":55},[45,791,311],{"class":260},[45,793,795],{"class":47,"line":794},58,[45,796,797],{"class":340},"                        \u002F\u002F REQUIRED: without replay provisions a captured request verifies\n",[45,799,801],{"class":47,"line":800},59,[45,802,803],{"class":340},"                        \u002F\u002F forever. The host signs `\u003Ctimestamp>.\u003CrawBody>`.\n",[45,805,807,810,813,816,819],{"class":47,"line":806},60,[45,808,809],{"class":260},"                        replay: { timestampHeader: ",[45,811,812],{"class":55},"'x-acme-relay-timestamp'",[45,814,815],{"class":260},", toleranceSeconds: ",[45,817,818],{"class":65},"300",[45,820,444],{"class":260},[45,822,824],{"class":47,"line":823},61,[45,825,572],{"class":260},[45,827,829],{"class":47,"line":828},62,[45,830,831],{"class":260},"                },\n",[45,833,835],{"class":47,"line":834},63,[45,836,837],{"class":340},"                \u002F\u002F Declaring an identity IS `domainVerification: 'api'` for this kind.\n",[45,839,841,844,847],{"class":47,"line":840},64,[45,842,843],{"class":260},"                domainIdentity: { module: { exportPath: ",[45,845,846],{"class":55},"'.\u002Fconvex\u002FdomainIdentity'",[45,848,849],{"class":260}," } },\n",[45,851,853],{"class":47,"line":852},65,[45,854,855],{"class":260},"            },\n",[45,857,859],{"class":47,"line":858},66,[45,860,861],{"class":260},"        ],\n",[45,863,865],{"class":47,"line":864},67,[45,866,392],{"class":260},[45,868,870],{"class":47,"line":869},68,[45,871,872],{"class":260},"});\n",[11,874,875,876,879,880,883,884,887,888,891],{},"Alles Ausführbare liegt an einem ",[42,877,878],{},"module.exportPath",", den Ihr Package exportiert, und jedes davon wird als ",[15,881,882],{},"Default-Export"," dieses Moduls importiert — ebenso wie das Manifest an Ihrem Package-Root. Die Codegen verifiziert jeden Pfad, ohne ihn auszuführen; der Host importiert das Modul erst, wenn ein Versand, eine Zustellung oder eine Identitätsprüfung es tatsächlich benötigt. Exportieren Sie zusätzlich gern benannt, aber ein Modul mit ",[20,885,886],{},"ausschließlich"," benanntem Export komponiert zu einem Registry-Eintrag, dessen Modul ",[42,889,890],{},"undefined"," ist — und der erste Versand ist dann dasjenige, das es herausfindet. Das Scaffold erzeugt beides.",[115,893,895],{"id":894},"die-provider-checkliste-auf-beiden-stufen","Die Provider-Checkliste, auf beiden Stufen",[11,897,898,899,902,903,906],{},"Dieselben sechs Schritte, auf welcher Stufe Sie auch sind. ",[15,900,901],{},"Nichts sonst"," — durchgesetzt von den Konformitäts-Suites, die über Katalogarten iterieren statt über eine Liste, und von der ",[42,904,905],{},"lint:providers","-Ratsche, die jeden Vergleich gegen ein Provider-Art-Literal außerhalb eines Adapter-Ordners fehlschlagen lässt.",[11,908,909,910,914,915,918],{},"Die Core-Spalte unten ist eine Zusammenfassung. ",[224,911,913],{"href":912},"\u002Fdeveloper\u002Fproviders#send-email--the-provider-n1-checklist","Send-Provider → die Provider-N+1-Checkliste"," ist die kanonische Liste der Core-Stufe, mit den exakten Dateipfaden, den Compile-Zeit-Schutzmechanismen hinter jedem Schritt und dem einen ",[15,916,917],{},"optionalen"," Schritt, den diese Tabelle nicht enthält.",[120,920,921,934],{},[123,922,923],{},[126,924,925,928,931],{},[129,926,927],{},"#",[129,929,930],{},"Core-Art",[129,932,933],{},"Plugin-Art",[139,935,936,961,988,1007,1021,1038],{},[126,937,938,941,956],{},[144,939,940],{},"1",[144,942,943,944,947,948,951,952,955],{},"Katalogeintrag in ",[42,945,946],{},"packages\u002Fshared\u002Fsrc\u002FsendProviderCatalog.ts"," (Art, Capabilities, Felder für Zugangsdaten — die Union erweitert sich selbst; das Feld-Vokabular liegt in ",[42,949,950],{},"sendProviderCatalogTypes.ts"," und die Formular-Deskriptoren in ",[42,953,954],{},"sendProviderCredentialFields.ts",")",[144,957,958,960],{},[42,959,152],{},"-Contribution im Package-Manifest, mit denselben Capability-Feldern",[126,962,963,966,977],{},[144,964,965],{},"2",[144,967,968,969,972,973,976],{},"Env-Keys in ",[42,970,971],{},"lib\u002Fenv.ts"," und den ",[42,974,975],{},".env","-Beispielen",[144,978,979,980,983,984,987],{},"Env-Keys deklariert in den ",[42,981,982],{},"requiredEnvVars"," der Contribution (der Host prüft ihr Vorhandensein; ",[42,985,986],{},"lint:env"," bleibt unberührt)",[126,989,990,993,1000],{},[144,991,992],{},"3",[144,994,995,996,999],{},"Adapter-Ordner ",[42,997,998],{},"lib\u002FsendProviders\u002F\u003Ckind>\u002F"," (ein Vollständigkeits-Guard erzwingt ihn)",[144,1001,1002,1003,1006],{},"Export des Send-",[42,1004,1005],{},"module",", provenance-verifiziert und über einen Mapped-Type-Guard in der generierten Registry gepinnt",[126,1008,1009,1012,1015],{},[144,1010,1011],{},"4",[144,1013,1014],{},"Webhook-Adapter in der Feedback-Registry, falls der Provider Feedback meldet",[144,1016,1017,1018,1020],{},"Export des ",[42,1019,194],{},"-Moduls, falls der Provider Feedback meldet",[126,1022,1023,1026,1033],{},[144,1024,1025],{},"5",[144,1027,1028,1029,1032],{},"Domain-Identity-Provider in der Registry, falls die Verifikation ",[42,1030,1031],{},"api"," ist",[144,1034,1017,1035,1037],{},[42,1036,205],{},"-Moduls, falls der Provider Domains verifiziert",[126,1039,1040,1043,1046],{},[144,1041,1042],{},"6",[144,1044,1045],{},"Abschnitt auf der Docs-Seite",[144,1047,1048,1049],{},"Package-README; eingetragen in ",[42,1050,1051],{},"plugins.config.ts",[11,1053,1054,1055,1058],{},"Auf keiner der beiden Stufen ist eine Änderung an Routing, Dispatch, Ramp, Measurement oder Setup-Wizard ",[15,1056,1057],{},"erforderlich",". Wenn Sie dabei sind, eine vorzunehmen, fehlt die Capability, die Sie brauchen, im Vertrag — das ist eine Änderung am Vertrag, nicht an Ihrem Bundle.",[11,1060,1061,1062,1065,1066,1069,1070,1073,1074,1077,1078,1081,1082,1085],{},"Das Einzige, was eine Core-Art ",[15,1063,1064],{},"optional"," ergänzen darf, sind UI-Formulierungen: ",[42,1067,1068],{},"apps\u002Fweb"," führt ",[42,1071,1072],{},"Partial","-Override-Maps für das Label eines Transports, seinen DNS-Hinweisabsatz und seinen Picker-Text (Schritt 7 auf der kanonischen Liste). Eine Art ohne Zeile rendert aus ihrem Katalogeintrag — nichts bricht und nichts bleibt leer —, schreiben Sie also nur dann eine, wenn diese Oberfläche Ihren Provider anders formulieren soll. Eine ",[15,1075,1076],{},"Plugin-Art hat dazu überhaupt keinen entsprechenden Schritt",": Diese Maps sind über Core-Arten adressiert, und ein Bundle wird durch sein eigenes ",[42,1079,1080],{},"label"," und seine ",[42,1083,1084],{},"credentialFields"," beschrieben.",[115,1087,1089],{"id":1088},"semantik-der-capabilities","Semantik der Capabilities",[11,1091,1092],{},"Jedes Feld unten ist optional, und jedes hat denselben fail-closed-Default, den ein Core-Eintrag bekäme, der es weglässt, sodass ein gegen einen älteren Vertrag geschriebenes Manifest exakt so komponiert wie zuvor.",[120,1094,1095,1108],{},[123,1096,1097],{},[126,1098,1099,1102,1105],{},[129,1100,1101],{},"Feld",[129,1103,1104],{},"Was ein gebündelter Transport deklarieren darf",[129,1106,1107],{},"Was es verspricht",[139,1109,1110,1136,1168,1195,1213,1236,1251,1265],{},[126,1111,1112,1117,1122],{},[144,1113,1114],{},[42,1115,1116],{},"supportsCustomReturnPath",[144,1118,1119],{},[42,1120,1121],{},"no",[144,1123,1124,1125,1128,1129,1132,1133,1135],{},"Ob Owlat den Envelope-Sender wählen darf. ",[42,1126,1127],{},"yes"," und ",[42,1130,1131],{},"probe"," benötigen einen VERP-Local-Part, der mit einem Deployment-Secret signiert ist, das einem gebündelten Modul nie ausgehändigt wird — ",[42,1134,1121],{}," ist daher der einzige Wert dieser Stufe und der ehrliche dazu.",[126,1137,1138,1143,1151],{},[144,1139,1140],{},[42,1141,1142],{},"messageIdSource",[144,1144,1145,240,1148],{},[42,1146,1147],{},"provider",[42,1149,1150],{},"composed",[144,1152,1153,1154,1157,1158,1160,1161,1164,1165,1167],{},"Woher die Id stammt, die Ihr ",[42,1155,1156],{},"send"," zurückgibt: aus Ihrer eigenen API (",[42,1159,1147],{},") oder aus der ",[42,1162,1163],{},"Message-ID"," nach RFC 5322, die Owlat bereits erzeugt hat und die Sie zurückgespiegelt haben (",[42,1166,1150],{},"). Jedes Feedback-Ereignis wird darüber verknüpft.",[126,1169,1170,1175,1181],{},[144,1171,1172],{},[42,1173,1174],{},"deduplicatesOnIdempotencyKey",[144,1176,1177,240,1179],{},[42,1178,554],{},[42,1180,368],{},[144,1182,1183,1184,1186,1187,1190,1191,1194],{},"Ob derselbe Request unter einem Key zweimal gesendet werden darf, ohne zweimal zuzustellen. ",[42,1185,554],{}," zu deklarieren ",[15,1188,1189],{},"erfordert",", dass ",[42,1192,1193],{},"buildSystemMailExtras"," diesen Key in Ihren Request trägt; andernfalls verweigert der Host die Komposition, weil eine Behauptung ohne die Verdrahtung eine Doppelzustellung in einen \"sicheren\" Retry eines Passwort-Resets verwandelt.",[126,1196,1197,1202,1207],{},[144,1198,1199],{},[42,1200,1201],{},"hasProviderFeedback",[144,1203,1204],{},[20,1205,1206],{},"abgeleitet",[144,1208,1209,1210,1212],{},"Genau dann wahr, wenn die Contribution einen ",[42,1211,194],{}," deklariert.",[126,1214,1215,1220,1224],{},[144,1216,1217],{},[42,1218,1219],{},"domainVerification",[144,1221,1222],{},[20,1223,1206],{},[144,1225,1226,1228,1229,1231,1232,1235],{},[42,1227,1031],{}," genau dann, wenn die Contribution eine ",[42,1230,205],{}," deklariert, sonst ",[42,1233,1234],{},"none",".",[126,1237,1238,1243,1248],{},[144,1239,1240],{},[42,1241,1242],{},"acceptanceSemantics",[144,1244,1245],{},[20,1246,1247],{},"nicht deklarierbar",[144,1249,1250],{},"Gewahrsam über eine in Zustellung befindliche Nachricht. Nur Owlats eigener MTA deklariert das; das Timeout eines Dritten ist immer mehrdeutig.",[126,1252,1253,1258,1262],{},[144,1254,1255],{},[42,1256,1257],{},"tagsFeedbackProvenance",[144,1259,1260],{},[20,1261,1247],{},[144,1263,1264],{},"Besagt, dass unser eigener MTA den Report auf dem Weg aus unserer eigenen Infrastruktur gestempelt hat. Bei einem Dritten niemals wahr.",[126,1266,1267,1272,1276],{},[144,1268,1269],{},[42,1270,1271],{},"setupProbe",[144,1273,1274],{},[20,1275,1247],{},[144,1277,1278],{},"Benennt einen exportierten Validator in Host-Code, dem ein Manifest nichts hinzufügen kann.",[1280,1281,1283],"h3",{"id":1282},"konfiguration-und-benannte-instanzen","Konfiguration und benannte Instanzen",[11,1285,1286,1288,1289,1292,1293,1296,1297,1300,1301,1303,1304,1307,1308,1311,1312,1315],{},[42,1287,982],{}," auf der Contribution ist das, was ",[15,1290,1291],{},"eine Instanz"," Ihres Transports benötigt. Es zu deklarieren ist das, was benannte Instanzen möglich macht: Ein Deployment kann ",[42,1294,1295],{},"plugin.acme-relay.relay#eu"," betreiben, das ",[42,1298,1299],{},"PLUGIN_ACME_RELAY_API_KEY__EU"," liest, und der Host übergibt Ihrem ",[42,1302,1156],{}," genau die Werte dieser Instanz, adressiert über den Basisnamen, den Ihr Manifest geschrieben hat. Lesen Sie sie aus dem ",[42,1305,1306],{},"config","-Argument — ein Modul, das ",[42,1309,1310],{},"process.env"," liest, löst die Zugangsdaten der ",[20,1313,1314],{},"Deployment-Default","-Instanz auf, an welche Id der Versand auch adressiert war.",[11,1317,1318,1319,1322,1323,1326,1327,1330,1331,1334],{},"Namen unterliegen einer Regel: ",[42,1320,1321],{},"PLUGIN_","-präfigiert, Großbuchstaben, kein ",[42,1324,1325],{},"__"," (das ist der Instanz-Trenner) und kein abschließender ",[42,1328,1329],{},"_",". Die ",[42,1332,1333],{},"flag.requiredEnvVars"," des Plugins selbst sind ein anderer Scope — ein deploymentweiter Schalter, der ohne Suffix gelesen wird — und die beiden Listen dürfen sich nicht überschneiden.",[11,1336,1337,1340],{},[42,1338,1339],{},"optionalEnvVars"," wird ohne mindestens eine erforderliche Variable abgelehnt: Ein Transport, dessen gesamte Konfiguration optional ist, hat keine Zugangsdaten pro Instanz aufzulösen, sodass jede benannte Instanz davon gegen eine leere Anforderungsliste bewertet würde.",[1280,1342,1344],{"id":1343},"das-formular-für-zugangsdaten","Das Formular für Zugangsdaten",[11,1346,1347,1349,1350,1353,1354,240,1357,240,1360,240,1363,240,1366,1369,1370,1373,1374,1377,1378,1381],{},[42,1348,1084],{}," sind typisierte Deskriptoren in demselben Vokabular, das das ",[42,1351,1352],{},"settingsSchema"," der Plattform verwendet — ",[42,1355,1356],{},"string",[42,1358,1359],{},"secret",[42,1361,1362],{},"number",[42,1364,1365],{},"boolean",[42,1367,1368],{},"select"," —, sodass ein einziger Renderer Ihre Zugangsdaten so zeichnet, wie er die eines Core-Providers zeichnet. Sie sind ",[15,1371,1372],{},"rein beschreibend",": Nichts davon entscheidet, was ein Versand liest. Das ",[42,1375,1376],{},"envVar"," jedes Felds muss eine Variable sein, die dieser Transport deklariert hat, abgeglichen mit dem ",[42,1379,1380],{},"required"," des Felds selbst — und genau das verhindert, dass ein gerendertes Formular nach einer Variable fragt, die kein Versand liest, oder eine weglässt, die den Transport gatet.",[115,1383,1385],{"id":1384},"sicherheitserwartungen-an-den-webhook","Sicherheitserwartungen an den Webhook",[11,1387,1388,1389,1392],{},"Ihr Feedback-Modul ",[15,1390,1391],{},"parst",". Es entscheidet niemals, ob ein Request authentisch ist. Bis es läuft, hat der Host bereits:",[1394,1395,1396,1400,1407,1410,1417,1420,1423],"ol",{},[1397,1398,1399],"li",{},"ein Rate-Limit-Token pro Plugin verbraucht — der eine Schreibvorgang, den ein unbewiesener Aufrufer auslöst, und zwar zuerst, weil ein Limiter, der nicht aufzeichnet, nicht limitieren kann;",[1397,1401,1402,1403,1406],{},"die Route über die Plugin-Id aufgelöst (",[42,1404,1405],{},"POST \u002Fwebhooks\u002Fplugin\u002F\u003CpluginId>",") und für eine unbekannte mit 404 geantwortet, bevor ein einziges Byte des Bodys gelesen wurde;",[1397,1408,1409],{},"die Größe des Bodys begrenzt;",[1397,1411,1412,1413,1416],{},"Ihren deklarierten HMAC über ",[42,1414,1415],{},"\u003Ctimestamp>.\u003CrawBody>"," in konstanter Zeit neu berechnet und mit dem von Ihnen benannten Header verglichen;",[1397,1418,1419],{},"einen Zeitstempel abgelehnt, der weiter von jetzt entfernt ist als Ihre deklarierte Toleranz;",[1397,1421,1422],{},"die Capability-Gewährung des Operators unter einer eigenen auditierten Operation erneut geprüft;",[1397,1424,1425],{},"eine Zustellung abgelehnt, deren Signatur-Digest er bereits akzeptiert hat.",[11,1427,1428,1432,1433,1435],{},[224,1429,1431],{"href":1430},"\u002Fdeveloper\u002Fplugin-contributions#feedback-webhook","Contribution-Referenz → Feedback-Webhook"," ist die normative Liste dessen, was der ",[42,1434,194],{},"-Block enthalten muss — die Felder, die Toleranz-Obergrenze, in welchen der beiden Variablen-Scopes das Secret gehört und wie viele Webhooks ein Plugin deklarieren darf. Das ist die Seite, gegen die Sie Ihr Manifest schreiben; dieser Abschnitt erklärt, warum jede dieser Regeln existiert und was es kostet, sie falsch zu machen:",[1437,1438,1439,1448,1457,1463,1469],"ul",{},[1397,1440,1441,1447],{},[15,1442,1443,1446],{},[42,1444,1445],{},"signature"," ist erforderlich."," Ein Webhook ohne sie scheitert an der Manifest-Validierung. Dieser Endpoint ist per Design unauthentifiziert und zum Internet hin offen; ein unverifizierter wäre ein offener Schreibpfad in den Zustellungsdatensatz.",[1397,1449,1450,1456],{},[15,1451,1452,1455],{},[42,1453,1454],{},"replay","-Vorkehrungen sind ebenfalls erforderlich."," Ein HMAC allein über den Body beweist die Herkunft und sonst nichts — dieselben abgefangenen Bytes verifizieren für immer. Erst das Einbinden eines Zeitstempels in den signierten String und das Begrenzen seines Alters sorgt dafür, dass eine Zustellung einmal passiert. Die Obergrenze dieses Fensters gehört dem Kit, nicht Ihnen; wählen Sie die kleinste, die die Retries Ihres Providers vertragen, deutlich darunter.",[1397,1458,1459,1462],{},[15,1460,1461],{},"Das Signier-Secret gatet das Plugin, nicht den Transport."," Ohne es kann die Route nichts verifizieren und beantwortet jede Zustellung mit 503 — und eine Serie von Nicht-2xx ist genau das, was einen Provider dazu bringt, Ihren Endpoint zu deaktivieren —, deshalb darf das Plugin ohne es nicht aktivierbar sein. Darum wird es in dem Scope deklariert, den ein Deployment ohne Suffix liest, statt neben Ihren Zugangsdaten pro Instanz.",[1397,1464,1465,1468],{},[15,1466,1467],{},"Die Routen-Oberfläche ist über die Plugin-Id adressiert",", sodass ein zweiter Webhook im selben Plugin nie ansprechbar wäre; ein Manifest, das einen deklariert, wird abgelehnt statt stillschweigend ignoriert.",[1397,1470,1471,1474],{},[15,1472,1473],{},"Rohe Payloads werden nicht aufbewahrt, sofern Sie es nicht verlangen."," Die Payload eines Dritten kann Empfängerinhalte tragen, die dieses Deployment nie aufbewahren wollte, weshalb die Aufbewahrung Ihre explizite Entscheidung ist statt der Default der Pipeline.",[11,1476,1477,1478,1481,1482,1485],{},"Innerhalb des Moduls: Geben Sie für einen Verifikations-Ping aus der Konsole und für Ereignisarten, die Owlat nicht konsumiert, das leere Array zurück — ein 400 würde Ihren Provider dazu bringen, sie für immer erneut zuzustellen — und ",[15,1479,1480],{},"werfen"," Sie bei einem Body, den Sie nicht lesen können. Lesen Sie den Zeitstempel eines Ereignisses nur für die Arten, die Sie ",[20,1483,1484],{},"tatsächlich"," konsumieren: Ein Engagement-Ereignis, das Sie ignorieren, lässt das Feld womöglich ganz weg, und es oberhalb Ihres Art-Switches zu validieren reißt den gesamten Batch mit hinunter. Importieren Sie keine Node-Builtins: Das Modul wird vom HTTP-Router geladen.",[115,1487,182],{"id":1488},"sending-domain-identität",[11,1490,1491,1492,1495],{},"Ihr Identitätsmodul meldet ",[15,1493,1494],{},"Beobachtungen",", niemals ein Verdikt: ob der Provider die Inhaberschaft bestätigt hat, seine Verdikte zu den veröffentlichten SPF- und DKIM-Records, die DKIM-Selektoren, unter denen er signiert, und die SPF-Mechanismen, für die er eine Autorisierung braucht. Der Host leitet den Status daraus ab, sodass \"verifiziert\" auf jeder Relay-Stufe dasselbe bedeutet und ein Modul eine Domain nicht als verifiziert melden kann, während es uns mitteilt, dass ihr DKIM ungültig ist. Die Frische-Grenze dieses Nachweises ist eine Host-Konstante, kein Manifest-Feld.",[11,1497,1498,1499,1502,1503,1506,1507,1510],{},"Unterscheiden Sie die drei Ergebnisse, denn die Schreibregeln des Hosts sind für jedes andere: ",[42,1500,1501],{},"ok"," ist das einzige, das das Alter des Nachweises auffrischt, ",[42,1504,1505],{},"auth_failed"," verurteilt ein Credential, ohne die bereits gespeicherten DNS-Verdikte zu überschreiben, und ",[42,1508,1509],{},"unavailable"," — als das auch ein geworfener Fehler gelesen wird — ändert nichts außer dem Retry.",[11,1512,1513],{},"Geben Sie Ihre DKIM-Selektoren zurück, wann immer Sie sie kennen. Eine leere Liste bedeutet \"wir können die Signier-Identität dieser Domain nicht beschreiben\", was der Alignment-Pre-Flight für Dual-Transport als Halt für die Ramp liest statt als geöffnetes Gate.",[115,1515,1517],{"id":1516},"was-das-scaffold-ihnen-gibt","Was das Scaffold Ihnen gibt",[11,1519,1520,1521,1523,1524,1128,1527,1530,1531,1534],{},"Jedes Template schreibt dasselbe Package-Skelett aus drei Dateien — ",[42,1522,100],{}," (private, mit der Export-Map, gegen die die Modulpfade Ihres Manifests geprüft werden), ",[42,1525,1526],{},"tsconfig.json",[42,1528,1529],{},"vitest.config.ts",". Darüber hinaus erzeugt ",[42,1532,1533],{},"owlat plugins create \u003Cid> --template send-provider",":",[120,1536,1537,1547],{},[123,1538,1539],{},[126,1540,1541,1544],{},[129,1542,1543],{},"Datei",[129,1545,1546],{},"Was sie enthält",[139,1548,1549,1559,1569,1578,1588,1601,1611,1621,1631,1641,1651],{},[126,1550,1551,1556],{},[144,1552,1553],{},[42,1554,1555],{},"README.md",[144,1557,1558],{},"Was erledigt ist, was übrig bleibt, welche Umgebungsvariablen ein Operator setzt und wie Sie das Package aus dem Checkout herauslösen und veröffentlichen",[126,1560,1561,1566],{},[144,1562,1563],{},[42,1564,1565],{},"src\u002Findex.ts",[144,1567,1568],{},"Der Root-Export des Packages: das Manifest, sonst nichts",[126,1570,1571,1575],{},[144,1572,1573],{},[42,1574,218],{},[144,1576,1577],{},"Die reine Daten-Deklaration: Capabilities, Formular für Zugangsdaten, Signaturvertrag",[126,1579,1580,1585],{},[144,1581,1582],{},[42,1583,1584],{},"src\u002FenvNames.ts",[144,1586,1587],{},"Jeder Umgebungsvariablenname, einmal deklariert und sowohl vom Manifest als auch von den Modulen gelesen",[126,1589,1590,1595],{},[144,1591,1592],{},[42,1593,1594],{},"src\u002Fconvex\u002Ftransport.ts",[144,1596,1597,1598,1600],{},"Der Sendepfad: ein Versuch, Zugangsdaten aus ",[42,1599,1306],{},", Status auf das Retry-Vokabular des Hosts abgebildet",[126,1602,1603,1608],{},[144,1604,1605],{},[42,1606,1607],{},"src\u002Fconvex\u002Fwebhook.ts",[144,1609,1610],{},"Der Feedback-Pfad: nur Parsing, isolate-sicher",[126,1612,1613,1618],{},[144,1614,1615],{},[42,1616,1617],{},"src\u002Fconvex\u002FdomainIdentity.ts",[144,1619,1620],{},"Die Sending-Domain-Identität: nur Beobachtungen, drei unterscheidbare Ergebnisse",[126,1622,1623,1628],{},[144,1624,1625],{},[42,1626,1627],{},"src\u002F__tests__\u002Fmanifest.test.ts",[144,1629,1630],{},"Das Manifest validiert und hält die beiden Variablen-Scopes auseinander",[126,1632,1633,1638],{},[144,1634,1635],{},[42,1636,1637],{},"src\u002F__tests__\u002Ftransport.test.ts",[144,1639,1640],{},"Zugangsdaten kommen aus der Instanzkonfiguration; das Status-Mapping hält",[126,1642,1643,1648],{},[144,1644,1645],{},[42,1646,1647],{},"src\u002F__tests__\u002Fwebhook.test.ts",[144,1649,1650],{},"Die vier Feedback-Fakten, der quittierte Ping, der unlesbare Body",[126,1652,1653,1658],{},[144,1654,1655],{},[42,1656,1657],{},"src\u002F__tests__\u002FdomainIdentity.test.ts",[144,1659,1660],{},"Beobachtungen sowie ein abgelehntes Credential, unterschieden von einem Ausfall",[11,1662,1663],{},"Das erzeugte Bundle ist keine Skizze: Es komponiert, und Owlats eigenes Konformitäts-Gate treibt die Ausgabe des Generators — unverändert — bei jedem CI-Lauf durch die ausgelieferten Routing-, Dispatch-, Feedback- und Identitätsmodule.",[115,1665,1667],{"id":1666},"wie-es-weitergeht","Wie es weitergeht",[1437,1669,1670,1680,1691,1710],{},[1397,1671,1672,1676,1677,1679],{},[224,1673,1675],{"href":1674},"\u002Fdeveloper\u002Fplugin-contributions","Contribution-Referenz"," — der ",[42,1678,152],{},"-Bucket neben jedem anderen Bucket, mit den Modulverträgen in voller Länge.",[1397,1681,1682,1686,1687,1690],{},[224,1683,1685],{"href":1684},"\u002Fdeveloper\u002Fplugin-capabilities","Capabilities & Vertrauen"," — was ",[42,1688,1689],{},"send:transport"," gewährt und wie ein Operator es widerruft.",[1397,1692,1693,1697,1698,240,1701,240,1704,240,1707,1235],{},[224,1694,1696],{"href":1695},"\u002Fdeveloper\u002Fplugin-cli","Die owlat-plugins-CLI"," — ",[42,1699,1700],{},"create",[42,1702,1703],{},"add",[42,1705,1706],{},"remove",[42,1708,1709],{},"codegen",[1397,1711,1712,1715],{},[224,1713,17],{"href":1714},"\u002Fdeveloper\u002Fproviders"," — der Katalog der Core-Stufe und die Capability-Tabelle pro Provider.",[1717,1718,1719],"style",{},"html pre.shiki code .sOLd2, html code.shiki .sOLd2{--shiki-default:#6F42C1;--shiki-dark:#F69D50}html pre.shiki code .s-HuK, html code.shiki .s-HuK{--shiki-default:#032F62;--shiki-dark:#96D0FF}html pre.shiki code .sviXB, html code.shiki .sviXB{--shiki-default:#005CC5;--shiki-dark:#6CB6FF}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);}html pre.shiki code .s7YZ4, html code.shiki .s7YZ4{--shiki-default:#D73A49;--shiki-dark:#F47067}html pre.shiki code .sYgZi, html code.shiki .sYgZi{--shiki-default:#24292E;--shiki-dark:#ADBAC7}html pre.shiki code .sPO5f, html code.shiki .sPO5f{--shiki-default:#6F42C1;--shiki-dark:#DCBDFB}html pre.shiki code .sDN9O, html code.shiki .sDN9O{--shiki-default:#6A737D;--shiki-dark:#768390}",{"title":40,"searchDepth":273,"depth":273,"links":1721},[1722,1723,1724,1728,1729,1730,1731],{"id":117,"depth":273,"text":118},{"id":894,"depth":273,"text":895},{"id":1088,"depth":273,"text":1089,"children":1725},[1726,1727],{"id":1282,"depth":280,"text":1283},{"id":1343,"depth":280,"text":1344},{"id":1384,"depth":273,"text":1385},{"id":1488,"depth":273,"text":182},{"id":1516,"depth":273,"text":1517},{"id":1666,"depth":273,"text":1667},"Der Bundle-Vertrag für Send-Provider, die zweistufige Provider-Checkliste, die Semantik der Capabilities und was der Host für Ihren Feedback-Webhook garantiert.","md",{},"\u002Fdeveloper\u002Fplugin-send-providers",{"title":6,"description":1732},"3.developer\u002F49.plugin-send-providers","2roNmI3Ahf1mbYr5UARb9w1BsJiBaj9dP283eEVtxYg",[1740,1744],{"title":1741,"path":1742,"stem":1743,"children":-1},"Plugin-Troubleshooting","\u002Fdeveloper\u002Fplugin-troubleshooting","3.developer\u002F48.plugin-troubleshooting",{"title":1745,"path":1746,"stem":1747,"children":-1},"Authentifizierung","\u002Fdeveloper\u002Fauthentication","3.developer\u002F5.authentication",1786915109563]