[{"data":1,"prerenderedAt":1504},["ShallowReactive",2],{"docs-nav":3,"content:\u002Fguides\u002Fbulk-sms":78},[4,18,29,35,46,63,66,69,72,75],{"path":5,"title":6,"navTitle":6,"order":7,"subnav":8},"\u002Fapi\u002Fapi-tokens","API tokens",3,[9,12,15],{"title":10,"anchor":11},"Create an API key","create-an-api-key",{"title":13,"anchor":14},"List API keys","list-api-keys",{"title":16,"anchor":17},"Revoke an API key","revoke-an-api-key",{"path":19,"title":20,"navTitle":20,"order":21,"subnav":22},"\u002Fapi\u002Fbalances","Balances",4,[23,26],{"title":24,"anchor":25},"The balance object","the-balance-object",{"title":27,"anchor":28},"List balances","list-balances",{"path":30,"title":31,"navTitle":32,"order":33,"subnav":34},"\u002Fapi","API overview","Overview",1,null,{"path":36,"title":37,"navTitle":37,"order":38,"subnav":39},"\u002Fapi\u002Fsender-ids","Sender IDs",5,[40,43],{"title":41,"anchor":42},"The sender identity object","the-sender-identity-object",{"title":44,"anchor":45},"List sender IDs","list-sender-ids",{"path":47,"title":48,"navTitle":48,"order":49,"subnav":50},"\u002Fapi\u002Fsms","SMS",2,[51,54,57,60],{"title":52,"anchor":53},"The message object","the-message-object",{"title":55,"anchor":56},"Send an SMS","send-an-sms",{"title":58,"anchor":59},"Retrieve an SMS","retrieve-an-sms",{"title":61,"anchor":62},"Send bulk SMS","send-bulk-sms",{"path":64,"title":65,"navTitle":65,"order":49,"subnav":34},"\u002Fguides\u002Fauthentication","Authentication",{"path":67,"title":68,"navTitle":68,"order":7,"subnav":34},"\u002Fguides\u002Fbulk-sms","Bulk SMS",{"path":70,"title":71,"navTitle":71,"order":38,"subnav":34},"\u002Fguides\u002Fmcp","AI agents (MCP)",{"path":73,"title":74,"navTitle":74,"order":33,"subnav":34},"\u002Fguides\u002Fquickstart","Quickstart",{"path":76,"title":77,"navTitle":77,"order":21,"subnav":34},"\u002Fguides\u002Fwebhooks","Webhooks",{"id":79,"path":67,"title":68,"description":80,"navTitle":68,"order":7,"wide":81,"body":82,"seo":1500,"stem":1501,"extension":1502,"meta":1503,"navigation":399},"content\u002Fguides\u002Fbulk-sms.md","Send one SMS body to a list of recipients in a single call with POST \u002Fapi\u002Fv1\u002Fsms\u002Fbulk, and track each recipient's message individually.",false,{"type":83,"value":84,"toc":1493},"minimark",[85,102,107,121,615,629,893,900,915,925,935,939,942,1194,1231,1235,1238,1306,1416,1420,1462,1466,1489],[86,87,88,92,93,97,98,101],"p",{},[89,90,91],"code",{},"POST \u002Fapi\u002Fv1\u002Fsms\u002Fbulk"," sends the same body to every recipient in one call, prices the whole\nsend up front, and returns ",[94,95,96],"strong",{},"one message id per recipient",". Those ids behave exactly like\nsingle-send ids, so you track each recipient with ",[89,99,100],{},"GET \u002Fapi\u002Fv1\u002Fsms\u002F{id}",".",[103,104,106],"h2",{"id":105},"sending-to-a-list","Sending to a list",[86,108,109,112,113,116,117,120],{},[89,110,111],{},"to"," is an array of MSISDNs in international format; ",[89,114,115],{},"message"," and ",[89,118,119],{},"from"," apply to every\nrecipient.",[122,123,125,220,433],"code-group",{"title":124,"label":91},"Request",[126,127,133],"pre",{"className":128,"code":129,"filename":130,"language":131,"meta":132,"style":132},"language-bash shiki shiki-themes github-light github-dark","curl -X POST https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fsms\u002Fbulk \\\n  -H \"Authorization: Bearer $SENDAI_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\n    \"to\": [\"263771000000\", \"263772000001\"],\n    \"from\": \"YOUR_SENDER_ID\",\n    \"message\": \"Polls close at 18:00. Thanks for taking part!\",\n    \"webhook_url\": \"https:\u002F\u002Fexample.com\u002Fwebhooks\u002Fdlr\"\n  }'\n","cURL","bash","",[89,134,135,157,174,183,191,196,202,208,214],{"__ignoreMap":132},[136,137,139,143,147,151,154],"span",{"class":138,"line":33},"line",[136,140,142],{"class":141},"sScJk","curl",[136,144,146],{"class":145},"sj4cs"," -X",[136,148,150],{"class":149},"sZZnC"," POST",[136,152,153],{"class":149}," https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fsms\u002Fbulk",[136,155,156],{"class":145}," \\\n",[136,158,159,162,165,169,172],{"class":138,"line":49},[136,160,161],{"class":145},"  -H",[136,163,164],{"class":149}," \"Authorization: Bearer ",[136,166,168],{"class":167},"sVt8B","$SENDAI_API_KEY",[136,170,171],{"class":149},"\"",[136,173,156],{"class":145},[136,175,176,178,181],{"class":138,"line":7},[136,177,161],{"class":145},[136,179,180],{"class":149}," \"Content-Type: application\u002Fjson\"",[136,182,156],{"class":145},[136,184,185,188],{"class":138,"line":21},[136,186,187],{"class":145},"  -d",[136,189,190],{"class":149}," '{\n",[136,192,193],{"class":138,"line":38},[136,194,195],{"class":149},"    \"to\": [\"263771000000\", \"263772000001\"],\n",[136,197,199],{"class":138,"line":198},6,[136,200,201],{"class":149},"    \"from\": \"YOUR_SENDER_ID\",\n",[136,203,205],{"class":138,"line":204},7,[136,206,207],{"class":149},"    \"message\": \"Polls close at 18:00. Thanks for taking part!\",\n",[136,209,211],{"class":138,"line":210},8,[136,212,213],{"class":149},"    \"webhook_url\": \"https:\u002F\u002Fexample.com\u002Fwebhooks\u002Fdlr\"\n",[136,215,217],{"class":138,"line":216},9,[136,218,219],{"class":149},"  }'\n",[126,221,226],{"className":222,"code":223,"filename":224,"language":225,"meta":132,"style":132},"language-js shiki shiki-themes github-light github-dark","const res = await fetch('https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fsms\u002Fbulk', {\n  method: 'POST',\n  headers: {\n    'Authorization': `Bearer ${process.env.SENDAI_API_KEY}`,\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({\n    to: ['263771000000', '263772000001'],\n    from: 'YOUR_SENDER_ID',\n    message: 'Polls close at 18:00. Thanks for taking part!',\n    webhook_url: 'https:\u002F\u002Fexample.com\u002Fwebhooks\u002Fdlr',\n  }),\n})\n\nconst { data } = await res.json() \u002F\u002F enveloped — items under data.items\n","Node.js","js",[89,227,228,255,266,271,300,312,317,333,350,360,371,382,388,394,401],{"__ignoreMap":132},[136,229,230,234,237,240,243,246,249,252],{"class":138,"line":33},[136,231,233],{"class":232},"szBVR","const",[136,235,236],{"class":145}," res",[136,238,239],{"class":232}," =",[136,241,242],{"class":232}," await",[136,244,245],{"class":141}," fetch",[136,247,248],{"class":167},"(",[136,250,251],{"class":149},"'https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fsms\u002Fbulk'",[136,253,254],{"class":167},", {\n",[136,256,257,260,263],{"class":138,"line":49},[136,258,259],{"class":167},"  method: ",[136,261,262],{"class":149},"'POST'",[136,264,265],{"class":167},",\n",[136,267,268],{"class":138,"line":7},[136,269,270],{"class":167},"  headers: {\n",[136,272,273,276,279,282,285,287,290,292,295,298],{"class":138,"line":21},[136,274,275],{"class":149},"    'Authorization'",[136,277,278],{"class":167},": ",[136,280,281],{"class":149},"`Bearer ${",[136,283,284],{"class":167},"process",[136,286,101],{"class":149},[136,288,289],{"class":167},"env",[136,291,101],{"class":149},[136,293,294],{"class":145},"SENDAI_API_KEY",[136,296,297],{"class":149},"}`",[136,299,265],{"class":167},[136,301,302,305,307,310],{"class":138,"line":38},[136,303,304],{"class":149},"    'Content-Type'",[136,306,278],{"class":167},[136,308,309],{"class":149},"'application\u002Fjson'",[136,311,265],{"class":167},[136,313,314],{"class":138,"line":198},[136,315,316],{"class":167},"  },\n",[136,318,319,322,325,327,330],{"class":138,"line":204},[136,320,321],{"class":167},"  body: ",[136,323,324],{"class":145},"JSON",[136,326,101],{"class":167},[136,328,329],{"class":141},"stringify",[136,331,332],{"class":167},"({\n",[136,334,335,338,341,344,347],{"class":138,"line":210},[136,336,337],{"class":167},"    to: [",[136,339,340],{"class":149},"'263771000000'",[136,342,343],{"class":167},", ",[136,345,346],{"class":149},"'263772000001'",[136,348,349],{"class":167},"],\n",[136,351,352,355,358],{"class":138,"line":216},[136,353,354],{"class":167},"    from: ",[136,356,357],{"class":149},"'YOUR_SENDER_ID'",[136,359,265],{"class":167},[136,361,363,366,369],{"class":138,"line":362},10,[136,364,365],{"class":167},"    message: ",[136,367,368],{"class":149},"'Polls close at 18:00. Thanks for taking part!'",[136,370,265],{"class":167},[136,372,374,377,380],{"class":138,"line":373},11,[136,375,376],{"class":167},"    webhook_url: ",[136,378,379],{"class":149},"'https:\u002F\u002Fexample.com\u002Fwebhooks\u002Fdlr'",[136,381,265],{"class":167},[136,383,385],{"class":138,"line":384},12,[136,386,387],{"class":167},"  }),\n",[136,389,391],{"class":138,"line":390},13,[136,392,393],{"class":167},"})\n",[136,395,397],{"class":138,"line":396},14,[136,398,400],{"emptyLinePlaceholder":399},true,"\n",[136,402,404,406,409,412,415,418,420,423,426,429],{"class":138,"line":403},15,[136,405,233],{"class":232},[136,407,408],{"class":167}," { ",[136,410,411],{"class":145},"data",[136,413,414],{"class":167}," } ",[136,416,417],{"class":232},"=",[136,419,242],{"class":232},[136,421,422],{"class":167}," res.",[136,424,425],{"class":141},"json",[136,427,428],{"class":167},"() ",[136,430,432],{"class":431},"sJ8bj","\u002F\u002F enveloped — items under data.items\n",[126,434,439],{"className":435,"code":436,"filename":437,"language":438,"meta":132,"style":132},"language-python shiki shiki-themes github-light github-dark","import os\nimport requests\n\nres = requests.post(\n    \"https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fsms\u002Fbulk\",\n    headers={\"Authorization\": f\"Bearer {os.environ['SENDAI_API_KEY']}\"},\n    json={\n        \"to\": [\"263771000000\", \"263772000001\"],\n        \"from\": \"YOUR_SENDER_ID\",\n        \"message\": \"Polls close at 18:00. Thanks for taking part!\",\n        \"webhook_url\": \"https:\u002F\u002Fexample.com\u002Fwebhooks\u002Fdlr\",\n    },\n)\n\ndata = res.json()[\"data\"]  # enveloped — items under data[\"items\"]\n","Python","python",[89,440,441,449,456,460,470,477,518,528,546,558,570,582,587,592,596],{"__ignoreMap":132},[136,442,443,446],{"class":138,"line":33},[136,444,445],{"class":232},"import",[136,447,448],{"class":167}," os\n",[136,450,451,453],{"class":138,"line":49},[136,452,445],{"class":232},[136,454,455],{"class":167}," requests\n",[136,457,458],{"class":138,"line":7},[136,459,400],{"emptyLinePlaceholder":399},[136,461,462,465,467],{"class":138,"line":21},[136,463,464],{"class":167},"res ",[136,466,417],{"class":232},[136,468,469],{"class":167}," requests.post(\n",[136,471,472,475],{"class":138,"line":38},[136,473,474],{"class":149},"    \"https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fsms\u002Fbulk\"",[136,476,265],{"class":167},[136,478,479,483,485,488,491,493,496,499,501,504,507,510,513,515],{"class":138,"line":198},[136,480,482],{"class":481},"s4XuR","    headers",[136,484,417],{"class":232},[136,486,487],{"class":167},"{",[136,489,490],{"class":149},"\"Authorization\"",[136,492,278],{"class":167},[136,494,495],{"class":232},"f",[136,497,498],{"class":149},"\"Bearer ",[136,500,487],{"class":145},[136,502,503],{"class":167},"os.environ[",[136,505,506],{"class":149},"'SENDAI_API_KEY'",[136,508,509],{"class":167},"]",[136,511,512],{"class":145},"}",[136,514,171],{"class":149},[136,516,517],{"class":167},"},\n",[136,519,520,523,525],{"class":138,"line":204},[136,521,522],{"class":481},"    json",[136,524,417],{"class":232},[136,526,527],{"class":167},"{\n",[136,529,530,533,536,539,541,544],{"class":138,"line":210},[136,531,532],{"class":149},"        \"to\"",[136,534,535],{"class":167},": [",[136,537,538],{"class":149},"\"263771000000\"",[136,540,343],{"class":167},[136,542,543],{"class":149},"\"263772000001\"",[136,545,349],{"class":167},[136,547,548,551,553,556],{"class":138,"line":216},[136,549,550],{"class":149},"        \"from\"",[136,552,278],{"class":167},[136,554,555],{"class":149},"\"YOUR_SENDER_ID\"",[136,557,265],{"class":167},[136,559,560,563,565,568],{"class":138,"line":362},[136,561,562],{"class":149},"        \"message\"",[136,564,278],{"class":167},[136,566,567],{"class":149},"\"Polls close at 18:00. Thanks for taking part!\"",[136,569,265],{"class":167},[136,571,572,575,577,580],{"class":138,"line":373},[136,573,574],{"class":149},"        \"webhook_url\"",[136,576,278],{"class":167},[136,578,579],{"class":149},"\"https:\u002F\u002Fexample.com\u002Fwebhooks\u002Fdlr\"",[136,581,265],{"class":167},[136,583,584],{"class":138,"line":384},[136,585,586],{"class":167},"    },\n",[136,588,589],{"class":138,"line":390},[136,590,591],{"class":167},")\n",[136,593,594],{"class":138,"line":396},[136,595,400],{"emptyLinePlaceholder":399},[136,597,598,601,603,606,609,612],{"class":138,"line":403},[136,599,600],{"class":167},"data ",[136,602,417],{"class":232},[136,604,605],{"class":167}," res.json()[",[136,607,608],{"class":149},"\"data\"",[136,610,611],{"class":167},"]  ",[136,613,614],{"class":431},"# enveloped — items under data[\"items\"]\n",[86,616,617,618,621,622,624,625,628],{},"Unlike the single-send endpoint, this response ",[94,619,620],{},"is"," enveloped — the payload sits under\n",[89,623,411],{},", with one entry per recipient ",[94,626,627],{},"in request order",":",[122,630,632],{"title":631},"Response",[126,633,637],{"className":634,"code":635,"filename":636,"language":425,"meta":132,"style":132},"language-json shiki shiki-themes github-light github-dark","{\n  \"status\": \"success\",\n  \"message\": \"bulk sms enqueued\",\n  \"data\": {\n    \"total\": 2,\n    \"charge\": 900,\n    \"currency\": \"USD\",\n    \"items\": [\n      {\n        \"id\": \"0f9c1b3a-6d2e-4a1b-9c3d-7e5f2a8b4c10\",\n        \"to\": \"263771000000\",\n        \"status\": \"enqueued\",\n        \"operator\": \"econet\",\n        \"charge\": 450,\n        \"charge_currency\": \"USD\"\n      },\n      {\n        \"id\": \"7e5f2a8b-4c10-4a1b-9c3d-0f9c1b3a6d2e\",\n        \"to\": \"263772000001\",\n        \"status\": \"enqueued\",\n        \"operator\": \"netone\",\n        \"charge\": 450,\n        \"charge_currency\": \"USD\"\n      }\n    ]\n  }\n}\n","202 Accepted",[89,638,639,643,655,667,675,687,699,711,719,724,736,746,758,770,782,792,798,803,815,826,837,849,860,869,875,881,887],{"__ignoreMap":132},[136,640,641],{"class":138,"line":33},[136,642,527],{"class":167},[136,644,645,648,650,653],{"class":138,"line":49},[136,646,647],{"class":145},"  \"status\"",[136,649,278],{"class":167},[136,651,652],{"class":149},"\"success\"",[136,654,265],{"class":167},[136,656,657,660,662,665],{"class":138,"line":7},[136,658,659],{"class":145},"  \"message\"",[136,661,278],{"class":167},[136,663,664],{"class":149},"\"bulk sms enqueued\"",[136,666,265],{"class":167},[136,668,669,672],{"class":138,"line":21},[136,670,671],{"class":145},"  \"data\"",[136,673,674],{"class":167},": {\n",[136,676,677,680,682,685],{"class":138,"line":38},[136,678,679],{"class":145},"    \"total\"",[136,681,278],{"class":167},[136,683,684],{"class":145},"2",[136,686,265],{"class":167},[136,688,689,692,694,697],{"class":138,"line":198},[136,690,691],{"class":145},"    \"charge\"",[136,693,278],{"class":167},[136,695,696],{"class":145},"900",[136,698,265],{"class":167},[136,700,701,704,706,709],{"class":138,"line":204},[136,702,703],{"class":145},"    \"currency\"",[136,705,278],{"class":167},[136,707,708],{"class":149},"\"USD\"",[136,710,265],{"class":167},[136,712,713,716],{"class":138,"line":210},[136,714,715],{"class":145},"    \"items\"",[136,717,718],{"class":167},": [\n",[136,720,721],{"class":138,"line":216},[136,722,723],{"class":167},"      {\n",[136,725,726,729,731,734],{"class":138,"line":362},[136,727,728],{"class":145},"        \"id\"",[136,730,278],{"class":167},[136,732,733],{"class":149},"\"0f9c1b3a-6d2e-4a1b-9c3d-7e5f2a8b4c10\"",[136,735,265],{"class":167},[136,737,738,740,742,744],{"class":138,"line":373},[136,739,532],{"class":145},[136,741,278],{"class":167},[136,743,538],{"class":149},[136,745,265],{"class":167},[136,747,748,751,753,756],{"class":138,"line":384},[136,749,750],{"class":145},"        \"status\"",[136,752,278],{"class":167},[136,754,755],{"class":149},"\"enqueued\"",[136,757,265],{"class":167},[136,759,760,763,765,768],{"class":138,"line":390},[136,761,762],{"class":145},"        \"operator\"",[136,764,278],{"class":167},[136,766,767],{"class":149},"\"econet\"",[136,769,265],{"class":167},[136,771,772,775,777,780],{"class":138,"line":396},[136,773,774],{"class":145},"        \"charge\"",[136,776,278],{"class":167},[136,778,779],{"class":145},"450",[136,781,265],{"class":167},[136,783,784,787,789],{"class":138,"line":403},[136,785,786],{"class":145},"        \"charge_currency\"",[136,788,278],{"class":167},[136,790,791],{"class":149},"\"USD\"\n",[136,793,795],{"class":138,"line":794},16,[136,796,797],{"class":167},"      },\n",[136,799,801],{"class":138,"line":800},17,[136,802,723],{"class":167},[136,804,806,808,810,813],{"class":138,"line":805},18,[136,807,728],{"class":145},[136,809,278],{"class":167},[136,811,812],{"class":149},"\"7e5f2a8b-4c10-4a1b-9c3d-0f9c1b3a6d2e\"",[136,814,265],{"class":167},[136,816,818,820,822,824],{"class":138,"line":817},19,[136,819,532],{"class":145},[136,821,278],{"class":167},[136,823,543],{"class":149},[136,825,265],{"class":167},[136,827,829,831,833,835],{"class":138,"line":828},20,[136,830,750],{"class":145},[136,832,278],{"class":167},[136,834,755],{"class":149},[136,836,265],{"class":167},[136,838,840,842,844,847],{"class":138,"line":839},21,[136,841,762],{"class":145},[136,843,278],{"class":167},[136,845,846],{"class":149},"\"netone\"",[136,848,265],{"class":167},[136,850,852,854,856,858],{"class":138,"line":851},22,[136,853,774],{"class":145},[136,855,278],{"class":167},[136,857,779],{"class":145},[136,859,265],{"class":167},[136,861,863,865,867],{"class":138,"line":862},23,[136,864,786],{"class":145},[136,866,278],{"class":167},[136,868,791],{"class":149},[136,870,872],{"class":138,"line":871},24,[136,873,874],{"class":167},"      }\n",[136,876,878],{"class":138,"line":877},25,[136,879,880],{"class":167},"    ]\n",[136,882,884],{"class":138,"line":883},26,[136,885,886],{"class":167},"  }\n",[136,888,890],{"class":138,"line":889},27,[136,891,892],{"class":167},"}\n",[86,894,895,896,899],{},"Store each ",[89,897,898],{},"items[].id"," against your own recipient record — that id is how you check delivery\nlater.",[901,902,903],"blockquote",{},[86,904,905,911,912,914],{},[94,906,907,910],{},[89,908,909],{},"charge"," is an integer here."," The single-send endpoint returns it as a string. Both are\nin ten-thousandths of the currency (",[89,913,779],{}," == 0.045); only the JSON type differs.",[86,916,917,918,920,921,924],{},"Per-recipient ",[89,919,909],{}," values can differ within one send: operators are priced independently,\nso an Econet and a NetOne recipient may not cost the same. ",[89,922,923],{},"data.charge"," is the total held.",[86,926,927,928,931,932,101],{},"The optional ",[89,929,930],{},"webhook_url"," is validated as a URL and applied to every message in the send.\nFor delivery callbacks on your whole account rather than one send, see\n",[933,934,77],"a",{"href":76},[103,936,938],{"id":937},"tracking-each-recipient","Tracking each recipient",[86,940,941],{},"There is no batch-level status endpoint on this surface — you poll the individual message ids:",[122,943,944,969,1077],{"title":124,"label":100},[126,945,947],{"className":128,"code":946,"filename":130,"language":131,"meta":132,"style":132},"curl https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fsms\u002F0f9c1b3a-6d2e-4a1b-9c3d-7e5f2a8b4c10 \\\n  -H \"Authorization: Bearer $SENDAI_API_KEY\"\n",[89,948,949,958],{"__ignoreMap":132},[136,950,951,953,956],{"class":138,"line":33},[136,952,142],{"class":141},[136,954,955],{"class":149}," https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fsms\u002F0f9c1b3a-6d2e-4a1b-9c3d-7e5f2a8b4c10",[136,957,156],{"class":145},[136,959,960,962,964,966],{"class":138,"line":49},[136,961,161],{"class":145},[136,963,164],{"class":149},[136,965,168],{"class":167},[136,967,968],{"class":149},"\"\n",[126,970,972],{"className":222,"code":971,"filename":224,"language":225,"meta":132,"style":132},"const id = '0f9c1b3a-6d2e-4a1b-9c3d-7e5f2a8b4c10'\n\nconst res = await fetch(`https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fsms\u002F${id}`, {\n  headers: { 'Authorization': `Bearer ${process.env.SENDAI_API_KEY}` },\n})\n\nconst { data: sms } = await res.json() \u002F\u002F enveloped — the message is under data\n",[89,973,974,986,990,1014,1041,1045,1049],{"__ignoreMap":132},[136,975,976,978,981,983],{"class":138,"line":33},[136,977,233],{"class":232},[136,979,980],{"class":145}," id",[136,982,239],{"class":232},[136,984,985],{"class":149}," '0f9c1b3a-6d2e-4a1b-9c3d-7e5f2a8b4c10'\n",[136,987,988],{"class":138,"line":49},[136,989,400],{"emptyLinePlaceholder":399},[136,991,992,994,996,998,1000,1002,1004,1007,1010,1012],{"class":138,"line":7},[136,993,233],{"class":232},[136,995,236],{"class":145},[136,997,239],{"class":232},[136,999,242],{"class":232},[136,1001,245],{"class":141},[136,1003,248],{"class":167},[136,1005,1006],{"class":149},"`https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fsms\u002F${",[136,1008,1009],{"class":167},"id",[136,1011,297],{"class":149},[136,1013,254],{"class":167},[136,1015,1016,1019,1022,1024,1026,1028,1030,1032,1034,1036,1038],{"class":138,"line":21},[136,1017,1018],{"class":167},"  headers: { ",[136,1020,1021],{"class":149},"'Authorization'",[136,1023,278],{"class":167},[136,1025,281],{"class":149},[136,1027,284],{"class":167},[136,1029,101],{"class":149},[136,1031,289],{"class":167},[136,1033,101],{"class":149},[136,1035,294],{"class":145},[136,1037,297],{"class":149},[136,1039,1040],{"class":167}," },\n",[136,1042,1043],{"class":138,"line":38},[136,1044,393],{"class":167},[136,1046,1047],{"class":138,"line":198},[136,1048,400],{"emptyLinePlaceholder":399},[136,1050,1051,1053,1055,1057,1059,1062,1064,1066,1068,1070,1072,1074],{"class":138,"line":204},[136,1052,233],{"class":232},[136,1054,408],{"class":167},[136,1056,411],{"class":481},[136,1058,278],{"class":167},[136,1060,1061],{"class":145},"sms",[136,1063,414],{"class":167},[136,1065,417],{"class":232},[136,1067,242],{"class":232},[136,1069,422],{"class":167},[136,1071,425],{"class":141},[136,1073,428],{"class":167},[136,1075,1076],{"class":431},"\u002F\u002F enveloped — the message is under data\n",[126,1078,1080],{"className":435,"code":1079,"filename":437,"language":438,"meta":132,"style":132},"import os\nimport requests\n\nsms_id = \"0f9c1b3a-6d2e-4a1b-9c3d-7e5f2a8b4c10\"\n\nres = requests.get(\n    f\"https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fsms\u002F{sms_id}\",\n    headers={\"Authorization\": f\"Bearer {os.environ['SENDAI_API_KEY']}\"},\n)\n\nsms = res.json()[\"data\"]  # enveloped — the message is under data\n",[89,1081,1082,1088,1094,1098,1108,1112,1121,1140,1170,1174,1178],{"__ignoreMap":132},[136,1083,1084,1086],{"class":138,"line":33},[136,1085,445],{"class":232},[136,1087,448],{"class":167},[136,1089,1090,1092],{"class":138,"line":49},[136,1091,445],{"class":232},[136,1093,455],{"class":167},[136,1095,1096],{"class":138,"line":7},[136,1097,400],{"emptyLinePlaceholder":399},[136,1099,1100,1103,1105],{"class":138,"line":21},[136,1101,1102],{"class":167},"sms_id ",[136,1104,417],{"class":232},[136,1106,1107],{"class":149}," \"0f9c1b3a-6d2e-4a1b-9c3d-7e5f2a8b4c10\"\n",[136,1109,1110],{"class":138,"line":38},[136,1111,400],{"emptyLinePlaceholder":399},[136,1113,1114,1116,1118],{"class":138,"line":198},[136,1115,464],{"class":167},[136,1117,417],{"class":232},[136,1119,1120],{"class":167}," requests.get(\n",[136,1122,1123,1126,1129,1131,1134,1136,1138],{"class":138,"line":204},[136,1124,1125],{"class":232},"    f",[136,1127,1128],{"class":149},"\"https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fsms\u002F",[136,1130,487],{"class":145},[136,1132,1133],{"class":167},"sms_id",[136,1135,512],{"class":145},[136,1137,171],{"class":149},[136,1139,265],{"class":167},[136,1141,1142,1144,1146,1148,1150,1152,1154,1156,1158,1160,1162,1164,1166,1168],{"class":138,"line":210},[136,1143,482],{"class":481},[136,1145,417],{"class":232},[136,1147,487],{"class":167},[136,1149,490],{"class":149},[136,1151,278],{"class":167},[136,1153,495],{"class":232},[136,1155,498],{"class":149},[136,1157,487],{"class":145},[136,1159,503],{"class":167},[136,1161,506],{"class":149},[136,1163,509],{"class":167},[136,1165,512],{"class":145},[136,1167,171],{"class":149},[136,1169,517],{"class":167},[136,1171,1172],{"class":138,"line":216},[136,1173,591],{"class":167},[136,1175,1176],{"class":138,"line":362},[136,1177,400],{"emptyLinePlaceholder":399},[136,1179,1180,1183,1185,1187,1189,1191],{"class":138,"line":373},[136,1181,1182],{"class":167},"sms ",[136,1184,417],{"class":232},[136,1186,605],{"class":167},[136,1188,608],{"class":149},[136,1190,611],{"class":167},[136,1192,1193],{"class":431},"# enveloped — the message is under data\n",[86,1195,1196,1197,1200,1201,1204,1205,1204,1208,1211,1212,1215,1216,1219,1220,1226,1227,1230],{},"As with a single send, ",[89,1198,1199],{},"status"," tracks the pipeline (",[89,1202,1203],{},"created"," → ",[89,1206,1207],{},"enqueued",[89,1209,1210],{},"processing"," →\n",[89,1213,1214],{},"success"," \u002F ",[89,1217,1218],{},"failed",") and ",[94,1221,1222,1225],{},[89,1223,1224],{},"delivered_at"," is the delivery confirmation"," — ",[89,1228,1229],{},"null"," until the\ncarrier confirms, then a timestamp.",[103,1232,1234],{"id":1233},"errors","Errors",[86,1236,1237],{},"The whole send is accepted or rejected together; there is no partial success.",[1239,1240,1241,1254],"table",{},[1242,1243,1244],"thead",{},[1245,1246,1247,1251],"tr",{},[1248,1249,1250],"th",{},"Status",[1248,1252,1253],{},"Meaning",[1255,1256,1257,1283,1293],"tbody",{},[1245,1258,1259,1265],{},[1260,1261,1262],"td",{},[89,1263,1264],{},"400",[1260,1266,1267,1268,1270,1271,1273,1274,1276,1277,1279,1280,101],{},"Validation failed — ",[89,1269,111],{}," empty, ",[89,1272,115],{}," or ",[89,1275,119],{}," blank, or ",[89,1278,930],{}," not a URL. The body lists the offending fields in ",[89,1281,1282],{},"error.validation_errors",[1245,1284,1285,1290],{},[1260,1286,1287],{},[89,1288,1289],{},"401",[1260,1291,1292],{},"Missing, malformed, or revoked API key.",[1245,1294,1295,1300],{},[1260,1296,1297],{},[89,1298,1299],{},"422",[1260,1301,1302,1305],{},[89,1303,1304],{},"insufficient balance"," — your prepaid balance does not cover the send.",[122,1307,1308],{"title":631},[126,1309,1312],{"className":634,"code":1310,"filename":1311,"language":425,"meta":132,"style":132},"{\n  \"status\": \"error\",\n  \"message\": \"Validation failed\",\n  \"error\": {\n    \"code\": \"VALIDATION_ERROR\",\n    \"description\": \"One or more fields failed validation\",\n    \"validation_errors\": [\n      { \"field\": \"from\", \"description\": \"cannot be blank\" }\n    ]\n  }\n}\n","400 Bad Request",[89,1313,1314,1318,1329,1340,1347,1359,1371,1378,1404,1408,1412],{"__ignoreMap":132},[136,1315,1316],{"class":138,"line":33},[136,1317,527],{"class":167},[136,1319,1320,1322,1324,1327],{"class":138,"line":49},[136,1321,647],{"class":145},[136,1323,278],{"class":167},[136,1325,1326],{"class":149},"\"error\"",[136,1328,265],{"class":167},[136,1330,1331,1333,1335,1338],{"class":138,"line":7},[136,1332,659],{"class":145},[136,1334,278],{"class":167},[136,1336,1337],{"class":149},"\"Validation failed\"",[136,1339,265],{"class":167},[136,1341,1342,1345],{"class":138,"line":21},[136,1343,1344],{"class":145},"  \"error\"",[136,1346,674],{"class":167},[136,1348,1349,1352,1354,1357],{"class":138,"line":38},[136,1350,1351],{"class":145},"    \"code\"",[136,1353,278],{"class":167},[136,1355,1356],{"class":149},"\"VALIDATION_ERROR\"",[136,1358,265],{"class":167},[136,1360,1361,1364,1366,1369],{"class":138,"line":198},[136,1362,1363],{"class":145},"    \"description\"",[136,1365,278],{"class":167},[136,1367,1368],{"class":149},"\"One or more fields failed validation\"",[136,1370,265],{"class":167},[136,1372,1373,1376],{"class":138,"line":204},[136,1374,1375],{"class":145},"    \"validation_errors\"",[136,1377,718],{"class":167},[136,1379,1380,1383,1386,1388,1391,1393,1396,1398,1401],{"class":138,"line":210},[136,1381,1382],{"class":167},"      { ",[136,1384,1385],{"class":145},"\"field\"",[136,1387,278],{"class":167},[136,1389,1390],{"class":149},"\"from\"",[136,1392,343],{"class":167},[136,1394,1395],{"class":145},"\"description\"",[136,1397,278],{"class":167},[136,1399,1400],{"class":149},"\"cannot be blank\"",[136,1402,1403],{"class":167}," }\n",[136,1405,1406],{"class":138,"line":216},[136,1407,880],{"class":167},[136,1409,1410],{"class":138,"line":362},[136,1411,886],{"class":167},[136,1413,1414],{"class":138,"line":373},[136,1415,892],{"class":167},[103,1417,1419],{"id":1418},"getting-bulk-sends-right","Getting bulk sends right",[1421,1422,1423,1434,1440,1450,1456],"ul",{},[1424,1425,1426,1429,1430,101],"li",{},[94,1427,1428],{},"Watch the encoding."," One non-GSM-7 character switches the whole body to UCS-2 and roughly\nhalves the characters per segment. Across 50,000 recipients that is a large and avoidable\nbill — see ",[933,1431,1433],{"href":1432},"\u002Fapi#billing-and-segments","billing and segments",[1424,1435,1436,1439],{},[94,1437,1438],{},"Deduplicate before you send."," A repeated MSISDN is not collapsed; the recipient gets two\nmessages and you are billed for both.",[1424,1441,1442,1445,1446,1449],{},[94,1443,1444],{},"Normalise to international format"," (",[89,1447,1448],{},"263771000000","). A number that does not resolve to an\noperator is a message you paid to have rejected.",[1424,1451,1452,1455],{},[94,1453,1454],{},"Make retries safe."," If a request times out, do not blindly resend — the send may well have\nbeen accepted. Reconcile against the returned ids first.",[1424,1457,1458,1461],{},[94,1459,1460],{},"Poll on an interval, not in a tight loop."," Delivery settles over minutes to hours, bounded\nby how fast carriers confirm.",[103,1463,1465],{"id":1464},"next-steps","Next steps",[1421,1467,1468,1473,1478,1483],{},[1424,1469,1470,1471],{},"Send a single message → ",[933,1472,74],{"href":73},[1424,1474,1475,1476],{},"Get delivery pushed instead of polling → ",[933,1477,77],{"href":76},[1424,1479,1480,1481],{},"Check your balance before a big send → ",[933,1482,20],{"href":19},[1424,1484,1485,1486],{},"Every field and response → ",[933,1487,61],{"href":1488},"\u002Fapi\u002Fsms#send-bulk-sms",[1490,1491,1492],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}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 .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":132,"searchDepth":49,"depth":49,"links":1494},[1495,1496,1497,1498,1499],{"id":105,"depth":49,"text":106},{"id":937,"depth":49,"text":938},{"id":1233,"depth":49,"text":1234},{"id":1418,"depth":49,"text":1419},{"id":1464,"depth":49,"text":1465},{"title":68,"description":80},"guides\u002Fbulk-sms","md",{},1786390037513]