[{"data":1,"prerenderedAt":577},["ShallowReactive",2],{"docs-page:\u002Fdocs\u002Fwebhooks":3,"docs-navigation":213,"docs-surround:\u002Fdocs\u002Fwebhooks":350,"icon:building-bank":355,"icon:building-store":381,"icon:chart-bar":396,"icon:chart-pie":409,"icon:code":416,"icon:discount":426,"icon:heart-handshake":440,"icon:mail-forward":453,"icon:messages":466,"icon:microphone-2":473,"icon:photo":480,"icon:plug-connected":493,"icon:school":512,"icon:speakerphone":519,"icon:stethoscope":529,"icon:trophy":545,"icon:user-plus":564},{"id":4,"title":5,"body":6,"description":200,"extension":201,"group":202,"meta":203,"navTitle":204,"navigation":205,"path":206,"rawbody":207,"seo":208,"status":209,"stem":210,"updated":211,"__hash__":212},"docs\u002Fdocs\u002F08.webhooks\u002F01.index.md","Webhooks",{"type":7,"value":8,"toc":193},"minimark",[9,13,77,85,90,93,126,134,138,147,150],[10,11,12],"p",{},"A webhook is a URL on your server that Wire2Air calls. Wire2Air sends three kinds:",[14,15,16,32],"table",{},[17,18,19],"thead",{},[20,21,22,26,29],"tr",{},[23,24,25],"th",{},"Webhook",[23,27,28],{},"When",[23,30,31],{},"Page",[33,34,35,50,63],"tbody",{},[20,36,37,41,44],{},[38,39,40],"td",{},"Inbound SMS",[38,42,43],{},"Someone texts your short code",[38,45,46],{},[47,48,40],"a",{"href":49},"\u002Fdocs\u002Fwebhooks\u002Finbound-sms\u002F",[20,51,52,55,58],{},[38,53,54],{},"Inbound SMS and MMS",[38,56,57],{},"Someone sends a message, including picture messages, to your short code",[38,59,60],{},[47,61,54],{"href":62},"\u002Fdocs\u002Fwebhooks\u002Finbound-mms\u002F",[20,64,65,68,71],{},[38,66,67],{},"Delivery report",[38,69,70],{},"A sent message's status changes",[38,72,73],{},[47,74,76],{"href":75},"\u002Fdocs\u002Fwebhooks\u002Fdelivery-reports\u002F","Delivery reports",[10,78,79,80,84],{},"All three are plain HTTP ",[81,82,83],"code",{},"GET"," requests with the data in the query string.",[86,87,89],"h2",{"id":88},"registering-your-url","Registering your URL",[10,91,92],{},"The documentation names three places a callback URL is set:",[94,95,96,113,123],"ul",{},[97,98,99,102,103,107,108,112],"li",{},[81,100,101],{},"ProcessorURL"," on a Developer API ",[47,104,106],{"href":105},"\u002Fdocs\u002Frest\u002Fcampaigns\u002F#create-a-campaign","campaign"," or a ",[47,109,111],{"href":110},"\u002Fdocs\u002Fhttp-api\u002Fkeyword-register\u002F","registered keyword",": where that keyword's incoming messages go.",[97,114,115,118,119,122],{},[81,116,117],{},"Replypath"," (REST) or ",[81,120,121],{},"ReplyPath"," (HTTP API) on a send request: where replies to that message go. The HTTP API docs say this is available \"case by case\", with the advanced developer API only.",[97,124,125],{},"Delivery reports need an Advanced Developer API account, according to the HTTP API send page.",[127,128,131],"callout",{"question":129,"type":130},"OQ-13","pending",[10,132,133],{},"How a delivery-report URL is registered, and which setting wins when several apply, is not documented.",[86,135,137],{"id":136},"build-a-safe-receiver","Build a safe receiver",[127,139,140],{"question":129,"type":130},[10,141,142,143,146],{},"The documentation does not say how to verify that a request really comes from Wire2Air (there is no signature or shared secret), whether Wire2Air retries a failed call, how long it waits, which response it expects, or whether callback URLs may use ",[81,144,145],{},"https:\u002F\u002F",".",[10,148,149],{},"Until those answers are published, build every receiver like this:",[94,151,152,162,172,178,184],{},[97,153,154,161],{},[155,156,157,158,146],"strong",{},"Answer quickly with ",[81,159,160],{},"200"," Store the request and process it afterwards, so a slow database does not cause a timeout.",[97,163,164,167,168,171],{},[155,165,166],{},"Expect duplicates."," Make processing idempotent, for example by remembering the message ID or the ",[81,169,170],{},"smsoutboxid"," you have already handled.",[97,173,174,177],{},[155,175,176],{},"Validate every value."," Treat each parameter as untrusted input; never put it into SQL or HTML unescaped.",[97,179,180,183],{},[155,181,182],{},"Use a URL that is hard to guess,"," for example one with a long random path segment, and change it if it leaks. Because requests are not signed, the URL is the only secret.",[97,185,186,192],{},[155,187,188,189,191],{},"Prefer an ",[81,190,145],{}," URL"," if your account accepts one, so message content is encrypted on the way to you.",{"title":194,"searchDepth":195,"depth":195,"links":196},"",3,[197,199],{"id":88,"depth":198,"text":89},2,{"id":136,"depth":198,"text":137},"How Wire2Air calls your server when a message arrives or a delivery report comes in, and how to build a receiver that is safe to expose.","md",null,{},"Overview",true,"\u002Fdocs\u002Fwebhooks","---\ntitle: Webhooks\nnavTitle: Overview\ndescription: How Wire2Air calls your server when a message arrives or a delivery report comes in, and how to build a receiver that is safe to expose.\nupdated: '2026-10-06'\n---\n\nA webhook is a URL on your server that Wire2Air calls. Wire2Air sends three kinds:\n\n| Webhook | When | Page |\n|---|---|---|\n| Inbound SMS | Someone texts your short code | [Inbound SMS](\u002Fdocs\u002Fwebhooks\u002Finbound-sms\u002F) |\n| Inbound SMS and MMS | Someone sends a message, including picture messages, to your short code | [Inbound SMS and MMS](\u002Fdocs\u002Fwebhooks\u002Finbound-mms\u002F) |\n| Delivery report | A sent message's status changes | [Delivery reports](\u002Fdocs\u002Fwebhooks\u002Fdelivery-reports\u002F) |\n\nAll three are plain HTTP `GET` requests with the data in the query string.\n\n## Registering your URL\n\nThe documentation names three places a callback URL is set:\n\n- `ProcessorURL` on a Developer API [campaign](\u002Fdocs\u002Frest\u002Fcampaigns\u002F#create-a-campaign) or a [registered keyword](\u002Fdocs\u002Fhttp-api\u002Fkeyword-register\u002F): where that keyword's incoming messages go.\n- `Replypath` (REST) or `ReplyPath` (HTTP API) on a send request: where replies to that message go. The HTTP API docs say this is available \"case by case\", with the advanced developer API only.\n- Delivery reports need an Advanced Developer API account, according to the HTTP API send page.\n\n::callout{type=\"pending\" question=\"OQ-13\"}\nHow a delivery-report URL is registered, and which setting wins when several apply, is not documented.\n::\n\n## Build a safe receiver\n\n::callout{type=\"pending\" question=\"OQ-13\"}\nThe documentation does not say how to verify that a request really comes from Wire2Air (there is no signature or shared secret), whether Wire2Air retries a failed call, how long it waits, which response it expects, or whether callback URLs may use `https:\u002F\u002F`.\n::\n\nUntil those answers are published, build every receiver like this:\n\n- **Answer quickly with `200`.** Store the request and process it afterwards, so a slow database does not cause a timeout.\n- **Expect duplicates.** Make processing idempotent, for example by remembering the message ID or the `smsoutboxid` you have already handled.\n- **Validate every value.** Treat each parameter as untrusted input; never put it into SQL or HTML unescaped.\n- **Use a URL that is hard to guess,** for example one with a long random path segment, and change it if it leaks. Because requests are not signed, the URL is the only secret.\n- **Prefer an `https:\u002F\u002F` URL** if your account accepts one, so message content is encrypted on the way to you.\n",{"title":5,"description":200},"current","docs\u002F08.webhooks\u002F01.index","2026-10-06","ROnwuVEmwMSF_7SSzaa31xMavLGEJdNnsjmo_qBapeI",[214],{"title":215,"path":216,"stem":217,"children":218,"navTitle":204,"group":202,"status":209},"Wire2Air developer docs","\u002Fdocs","docs\u002F01.index",[219,220,224,228,232,236,255,278,290,333,346],{"title":215,"path":216,"stem":217,"navTitle":204,"group":202,"status":209},{"title":221,"path":222,"stem":223,"navTitle":202,"group":221,"status":209},"Getting started","\u002Fdocs\u002Fgetting-started","docs\u002F02.getting-started",{"title":225,"path":226,"stem":227,"navTitle":202,"group":221,"status":209},"Authentication","\u002Fdocs\u002Fauthentication","docs\u002F03.authentication",{"title":229,"path":230,"stem":231,"navTitle":202,"group":221,"status":209},"Errors","\u002Fdocs\u002Ferrors","docs\u002F04.errors",{"title":233,"path":234,"stem":235,"navTitle":202,"group":221,"status":209},"Rate limits","\u002Fdocs\u002Frate-limits","docs\u002F05.rate-limits",{"title":237,"navTitle":202,"group":202,"status":209,"path":238,"stem":239,"children":240,"page":254},"Guides","\u002Fdocs\u002Fguides","docs\u002F06.guides",[241,246,250],{"title":242,"path":243,"stem":244,"navTitle":245,"group":202,"status":209},"Character encoding and message length","\u002Fdocs\u002Fguides\u002Fencoding","docs\u002F06.guides\u002F01.encoding","Encoding and length",{"title":247,"path":248,"stem":249,"navTitle":202,"group":202,"status":209},"Bulk messaging","\u002Fdocs\u002Fguides\u002Fbulk-messaging","docs\u002F06.guides\u002F02.bulk-messaging",{"title":251,"path":252,"stem":253,"navTitle":202,"group":202,"status":209},"Scheduling messages","\u002Fdocs\u002Fguides\u002Fscheduling","docs\u002F06.guides\u002F03.scheduling",false,{"title":256,"path":257,"stem":258,"children":259,"navTitle":202,"group":202,"status":209},"REST API v1","\u002Fdocs\u002Frest","docs\u002F07.rest\u002F01.index",[260,261,274],{"title":256,"path":257,"stem":258,"navTitle":204,"group":202,"status":209},{"title":262,"navTitle":202,"group":202,"status":209,"path":263,"stem":264,"children":265,"page":254},"Messages","\u002Fdocs\u002Frest\u002Fmessages","docs\u002F07.rest\u002F02.messages",[266,270],{"title":267,"path":268,"stem":269,"navTitle":202,"group":202,"status":209},"Send a message","\u002Fdocs\u002Frest\u002Fmessages\u002Fsend","docs\u002F07.rest\u002F02.messages\u002F01.send",{"title":271,"path":272,"stem":273,"navTitle":202,"group":202,"status":209},"List received messages","\u002Fdocs\u002Frest\u002Fmessages\u002Flist","docs\u002F07.rest\u002F02.messages\u002F02.list",{"title":275,"path":276,"stem":277,"navTitle":202,"group":202,"status":209},"Campaigns","\u002Fdocs\u002Frest\u002Fcampaigns","docs\u002F07.rest\u002F03.campaigns",{"title":5,"path":206,"stem":210,"children":279,"navTitle":202,"group":202,"status":209},[280,281,284,287],{"title":5,"path":206,"stem":210,"navTitle":204,"group":202,"status":209},{"title":40,"path":282,"stem":283,"navTitle":202,"group":202,"status":209},"\u002Fdocs\u002Fwebhooks\u002Finbound-sms","docs\u002F08.webhooks\u002F02.inbound-sms",{"title":54,"path":285,"stem":286,"navTitle":202,"group":202,"status":209},"\u002Fdocs\u002Fwebhooks\u002Finbound-mms","docs\u002F08.webhooks\u002F03.inbound-mms",{"title":76,"path":288,"stem":289,"navTitle":202,"group":202,"status":209},"\u002Fdocs\u002Fwebhooks\u002Fdelivery-reports","docs\u002F08.webhooks\u002F04.delivery-reports",{"title":291,"path":292,"stem":293,"children":294,"navTitle":202,"group":202,"status":296},"HTTP API","\u002Fdocs\u002Fhttp-api","docs\u002F09.http-api\u002F01.index",[295,297,301,305,309,313,317,321,325,329],{"title":291,"path":292,"stem":293,"navTitle":204,"group":202,"status":296},"legacy",{"title":298,"path":299,"stem":300,"navTitle":202,"group":202,"status":296},"Send SMS","\u002Fdocs\u002Fhttp-api\u002Fsend-sms","docs\u002F09.http-api\u002F02.send-sms",{"title":302,"path":303,"stem":304,"navTitle":202,"group":202,"status":296},"Send MMS","\u002Fdocs\u002Fhttp-api\u002Fsend-mms","docs\u002F09.http-api\u002F03.send-mms",{"title":306,"path":307,"stem":308,"navTitle":202,"group":202,"status":296},"Credit balance","\u002Fdocs\u002Fhttp-api\u002Fcredit-balance","docs\u002F09.http-api\u002F04.credit-balance",{"title":310,"path":311,"stem":312,"navTitle":202,"group":202,"status":296},"Carrier lookup","\u002Fdocs\u002Fhttp-api\u002Fcarrier-lookup","docs\u002F09.http-api\u002F05.carrier-lookup",{"title":314,"path":315,"stem":316,"navTitle":202,"group":202,"status":296},"Keyword lookup","\u002Fdocs\u002Fhttp-api\u002Fkeyword-lookup","docs\u002F09.http-api\u002F06.keyword-lookup",{"title":318,"path":319,"stem":320,"navTitle":202,"group":202,"status":296},"Keyword register","\u002Fdocs\u002Fhttp-api\u002Fkeyword-register","docs\u002F09.http-api\u002F07.keyword-register",{"title":322,"path":323,"stem":324,"navTitle":202,"group":202,"status":296},"Keyword credits","\u002Fdocs\u002Fhttp-api\u002Fkeyword-credits","docs\u002F09.http-api\u002F08.keyword-credits",{"title":326,"path":327,"stem":328,"navTitle":202,"group":202,"status":296},"Subscribe user","\u002Fdocs\u002Fhttp-api\u002Fsubscribe-user","docs\u002F09.http-api\u002F09.subscribe-user",{"title":330,"path":331,"stem":332,"navTitle":202,"group":202,"status":296},"Send invitation","\u002Fdocs\u002Fhttp-api\u002Fsend-invitation","docs\u002F09.http-api\u002F10.send-invitation",{"title":334,"navTitle":202,"group":202,"status":209,"path":335,"stem":336,"children":337,"page":254},"Integrations","\u002Fdocs\u002Fintegrations","docs\u002F10.integrations",[338,342],{"title":339,"path":340,"stem":341,"navTitle":202,"group":202,"status":209},"RSA Authentication Manager","\u002Fdocs\u002Fintegrations\u002Frsa-authentication-manager","docs\u002F10.integrations\u002F01.rsa-authentication-manager",{"title":343,"path":344,"stem":345,"navTitle":202,"group":202,"status":209},"Zapier","\u002Fdocs\u002Fintegrations\u002Fzapier","docs\u002F10.integrations\u002F02.zapier",{"title":347,"path":348,"stem":349,"navTitle":202,"group":202,"status":209},"Changelog","\u002Fdocs\u002Fchangelog","docs\u002F11.changelog",[351,353],{"title":275,"path":276,"stem":277,"description":352,"children":-1},"List, read, create, edit and delete Text2Join and Developer API campaigns with the REST API v1.",{"title":40,"path":282,"stem":283,"description":354,"children":-1},"Wire2Air forwards each text sent to your short code to your server as a GET request with the sender, the message, the time and the short code.",[356,360,363,366,369,372,375,378],[357,358],"path",{"d":359},"M3 21l18 0",[357,361],{"d":362},"M3 10l18 0",[357,364],{"d":365},"M5 6l7 -3l7 3",[357,367],{"d":368},"M4 10l0 11",[357,370],{"d":371},"M20 10l0 11",[357,373],{"d":374},"M8 14l0 3",[357,376],{"d":377},"M12 14l0 3",[357,379],{"d":380},"M16 14l0 3",[382,384,387,390,393],[357,383],{"d":359},[357,385],{"d":386},"M3 7v1a3 3 0 0 0 6 0v-1m0 1a3 3 0 0 0 6 0v-1m0 1a3 3 0 0 0 6 0v-1h-18l2 -4h14l2 4",[357,388],{"d":389},"M5 21l0 -10.15",[357,391],{"d":392},"M19 21l0 -10.15",[357,394],{"d":395},"M9 21v-4a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v4",[397,400,403,406],[357,398],{"d":399},"M3 13a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v6a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1l0 -6",[357,401],{"d":402},"M15 9a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v10a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1l0 -10",[357,404],{"d":405},"M9 5a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v14a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1l0 -14",[357,407],{"d":408},"M4 20h14",[410,413],[357,411],{"d":412},"M10 3.2a9 9 0 1 0 10.8 10.8a1 1 0 0 0 -1 -1h-6.8a2 2 0 0 1 -2 -2v-7a.9 .9 0 0 0 -1 -.8",[357,414],{"d":415},"M15 3.5a9 9 0 0 1 5.5 5.5h-4.5a1 1 0 0 1 -1 -1v-4.5",[417,420,423],[357,418],{"d":419},"M7 8l-4 4l4 4",[357,421],{"d":422},"M17 8l4 4l-4 4",[357,424],{"d":425},"M14 4l-4 16",[427,430,434,437],[357,428],{"d":429},"M9 15l6 -6",[357,431],{"d":432,"fill":433},"M9 9.5a.5 .5 0 1 0 1 0a.5 .5 0 1 0 -1 0","currentColor",[357,435],{"d":436,"fill":433},"M14 14.5a.5 .5 0 1 0 1 0a.5 .5 0 1 0 -1 0",[357,438],{"d":439},"M3 12a9 9 0 1 0 18 0a9 9 0 1 0 -18 0",[441,444,447,450],[357,442],{"d":443},"M19.5 12.572l-7.5 7.428l-7.5 -7.428a5 5 0 1 1 7.5 -6.566a5 5 0 1 1 7.5 6.572",[357,445],{"d":446},"M12 6l-3.293 3.293a1 1 0 0 0 0 1.414l.543 .543c.69 .69 1.81 .69 2.5 0l1 -1a3.182 3.182 0 0 1 4.5 0l2.25 2.25",[357,448],{"d":449},"M12.5 15.5l2 2",[357,451],{"d":452},"M15 13l2 2",[454,457,460,463],[357,455],{"d":456},"M12 18h-7a2 2 0 0 1 -2 -2v-10a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v7.5",[357,458],{"d":459},"M3 6l9 6l9 -6",[357,461],{"d":462},"M15 18h6",[357,464],{"d":465},"M18 15l3 3l-3 3",[467,470],[357,468],{"d":469},"M21 14l-3 -3h-7a1 1 0 0 1 -1 -1v-6a1 1 0 0 1 1 -1h9a1 1 0 0 1 1 1v10",[357,471],{"d":472},"M14 15v2a1 1 0 0 1 -1 1h-7l-3 3v-10a1 1 0 0 1 1 -1h2",[474,477],[357,475],{"d":476},"M15 12.9a5 5 0 1 0 -3.902 -3.9",[357,478],{"d":479},"M15 12.9l-3.902 -3.899l-7.513 8.584a2 2 0 1 0 2.827 2.83l8.588 -7.515",[481,484,487,490],[357,482],{"d":483},"M15 8h.01",[357,485],{"d":486},"M3 6a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v12a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3v-12",[357,488],{"d":489},"M3 16l5 -5c.928 -.893 2.072 -.893 3 0l5 5",[357,491],{"d":492},"M14 14l1 -1c.928 -.893 2.072 -.893 3 0l3 3",[494,497,500,503,506,509],[357,495],{"d":496},"M7 12l5 5l-1.5 1.5a3.536 3.536 0 1 1 -5 -5l1.5 -1.5",[357,498],{"d":499},"M17 12l-5 -5l1.5 -1.5a3.536 3.536 0 1 1 5 5l-1.5 1.5",[357,501],{"d":502},"M3 21l2.5 -2.5",[357,504],{"d":505},"M18.5 5.5l2.5 -2.5",[357,507],{"d":508},"M10 11l-2 2",[357,510],{"d":511},"M13 14l-2 2",[513,516],[357,514],{"d":515},"M22 9l-10 -4l-10 4l10 4l10 -4v6",[357,517],{"d":518},"M6 10.6v5.4a6 3 0 0 0 12 0v-5.4",[520,523,526],[357,521],{"d":522},"M18 8a3 3 0 0 1 0 6",[357,524],{"d":525},"M10 8v11a1 1 0 0 1 -1 1h-1a1 1 0 0 1 -1 -1v-5",[357,527],{"d":528},"M12 8l4.524 -3.77a.9 .9 0 0 1 1.476 .692v12.156a.9 .9 0 0 1 -1.476 .692l-4.524 -3.77h-8a1 1 0 0 1 -1 -1v-4a1 1 0 0 1 1 -1h8",[530,533,536,539,542],[357,531],{"d":532},"M6 4h-1a2 2 0 0 0 -2 2v3.5a5.5 5.5 0 0 0 11 0v-3.5a2 2 0 0 0 -2 -2h-1",[357,534],{"d":535},"M8 15a6 6 0 1 0 12 0v-3",[357,537],{"d":538},"M11 3v2",[357,540],{"d":541},"M6 3v2",[357,543],{"d":544},"M18 10a2 2 0 1 0 4 0a2 2 0 1 0 -4 0",[546,549,552,555,558,561],[357,547],{"d":548},"M8 21l8 0",[357,550],{"d":551},"M12 17l0 4",[357,553],{"d":554},"M7 4l10 0",[357,556],{"d":557},"M17 4v8a5 5 0 0 1 -10 0v-8",[357,559],{"d":560},"M3 9a2 2 0 1 0 4 0a2 2 0 1 0 -4 0",[357,562],{"d":563},"M17 9a2 2 0 1 0 4 0a2 2 0 1 0 -4 0",[565,568,571,574],[357,566],{"d":567},"M8 7a4 4 0 1 0 8 0a4 4 0 0 0 -8 0",[357,569],{"d":570},"M16 19h6",[357,572],{"d":573},"M19 16v6",[357,575],{"d":576},"M6 21v-2a4 4 0 0 1 4 -4h4",3529977955]