[{"data":1,"prerenderedAt":1759},["ShallowReactive",2],{"docs-nav":3,"content:\u002Fguides\u002Fauthentication":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":64,"title":65,"description":80,"navTitle":65,"order":49,"wide":81,"body":82,"seo":1755,"stem":1756,"extension":1757,"meta":1758,"navigation":336},"content\u002Fguides\u002Fauthentication.md","Authenticate to the Sendai SMS API with an API key sent as a bearer token — how to create one, keep it secret, rotate it, and revoke it.",false,{"type":83,"value":84,"toc":1746},"minimark",[85,99,123,126,131,138,507,621,631,643,647,650,942,948,1015,1019,1022,1227,1343,1368,1377,1381,1390,1592,1623,1642,1646,1649,1677,1680,1684,1714,1718,1742],[86,87,88,89,93,94,98],"p",{},"Every request to the Sendai SMS API is authenticated with an ",[90,91,92],"strong",{},"API key",", sent as a bearer\ntoken in the ",[95,96,97],"code",{},"Authorization"," header:",[100,101,106],"pre",{"className":102,"code":103,"language":104,"meta":105,"style":105},"language-http shiki shiki-themes github-light github-dark","Authorization: Bearer sk_live_4c8e…\n","http","",[95,107,108],{"__ignoreMap":105},[109,110,112,115,119],"span",{"class":111,"line":33},"line",[109,113,97],{"class":114},"s9eBZ",[109,116,118],{"class":117},"szBVR",":",[109,120,122],{"class":121},"sZZnC"," Bearer sk_live_4c8e…\n",[86,124,125],{},"There is nothing else to configure — no signing, no session to keep alive, no expiry to\nhandle. A key is valid from the moment you create it until you revoke it.",[127,128,130],"h2",{"id":129},"create-a-key","Create a key",[86,132,133,134,137],{},"Create keys from the ",[90,135,136],{},"Settings → Developer"," tab in the dashboard, or over the API. Give\neach key a name that identifies the service using it — you will be glad of it when you come\nto rotate.",[139,140,143,204,373],"code-group",{"title":141,"label":142},"Request","POST \u002Fapi\u002Fv1\u002Fapi-tokens",[100,144,149],{"className":145,"code":146,"filename":147,"language":148,"meta":105,"style":105},"language-bash shiki shiki-themes github-light github-dark","curl -X POST https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fapi-tokens \\\n  -H \"Authorization: Bearer $SENDAI_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{ \"name\": \"orders-service\" }'\n","cURL","bash",[95,150,151,170,187,196],{"__ignoreMap":105},[109,152,153,157,161,164,167],{"class":111,"line":33},[109,154,156],{"class":155},"sScJk","curl",[109,158,160],{"class":159},"sj4cs"," -X",[109,162,163],{"class":121}," POST",[109,165,166],{"class":121}," https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fapi-tokens",[109,168,169],{"class":159}," \\\n",[109,171,172,175,178,182,185],{"class":111,"line":49},[109,173,174],{"class":159},"  -H",[109,176,177],{"class":121}," \"Authorization: Bearer ",[109,179,181],{"class":180},"sVt8B","$SENDAI_API_KEY",[109,183,184],{"class":121},"\"",[109,186,169],{"class":159},[109,188,189,191,194],{"class":111,"line":7},[109,190,174],{"class":159},[109,192,193],{"class":121}," \"Content-Type: application\u002Fjson\"",[109,195,169],{"class":159},[109,197,198,201],{"class":111,"line":21},[109,199,200],{"class":159},"  -d",[109,202,203],{"class":121}," '{ \"name\": \"orders-service\" }'\n",[100,205,210],{"className":206,"code":207,"filename":208,"language":209,"meta":105,"style":105},"language-js shiki shiki-themes github-light github-dark","const res = await fetch('https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fapi-tokens', {\n  method: 'POST',\n  headers: {\n    'Authorization': `Bearer ${process.env.SENDAI_API_KEY}`,\n    'Content-Type': 'application\u002Fjson',\n  },\n  body: JSON.stringify({ name: 'orders-service' }),\n})\n\nconst { data } = await res.json()\n\u002F\u002F data.token is shown only in this response — store it now\n","Node.js","js",[95,211,212,238,249,254,284,296,302,325,331,338,366],{"__ignoreMap":105},[109,213,214,217,220,223,226,229,232,235],{"class":111,"line":33},[109,215,216],{"class":117},"const",[109,218,219],{"class":159}," res",[109,221,222],{"class":117}," =",[109,224,225],{"class":117}," await",[109,227,228],{"class":155}," fetch",[109,230,231],{"class":180},"(",[109,233,234],{"class":121},"'https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fapi-tokens'",[109,236,237],{"class":180},", {\n",[109,239,240,243,246],{"class":111,"line":49},[109,241,242],{"class":180},"  method: ",[109,244,245],{"class":121},"'POST'",[109,247,248],{"class":180},",\n",[109,250,251],{"class":111,"line":7},[109,252,253],{"class":180},"  headers: {\n",[109,255,256,259,262,265,268,271,274,276,279,282],{"class":111,"line":21},[109,257,258],{"class":121},"    'Authorization'",[109,260,261],{"class":180},": ",[109,263,264],{"class":121},"`Bearer ${",[109,266,267],{"class":180},"process",[109,269,270],{"class":121},".",[109,272,273],{"class":180},"env",[109,275,270],{"class":121},[109,277,278],{"class":159},"SENDAI_API_KEY",[109,280,281],{"class":121},"}`",[109,283,248],{"class":180},[109,285,286,289,291,294],{"class":111,"line":38},[109,287,288],{"class":121},"    'Content-Type'",[109,290,261],{"class":180},[109,292,293],{"class":121},"'application\u002Fjson'",[109,295,248],{"class":180},[109,297,299],{"class":111,"line":298},6,[109,300,301],{"class":180},"  },\n",[109,303,305,308,311,313,316,319,322],{"class":111,"line":304},7,[109,306,307],{"class":180},"  body: ",[109,309,310],{"class":159},"JSON",[109,312,270],{"class":180},[109,314,315],{"class":155},"stringify",[109,317,318],{"class":180},"({ name: ",[109,320,321],{"class":121},"'orders-service'",[109,323,324],{"class":180}," }),\n",[109,326,328],{"class":111,"line":327},8,[109,329,330],{"class":180},"})\n",[109,332,334],{"class":111,"line":333},9,[109,335,337],{"emptyLinePlaceholder":336},true,"\n",[109,339,341,343,346,349,352,355,357,360,363],{"class":111,"line":340},10,[109,342,216],{"class":117},[109,344,345],{"class":180}," { ",[109,347,348],{"class":159},"data",[109,350,351],{"class":180}," } ",[109,353,354],{"class":117},"=",[109,356,225],{"class":117},[109,358,359],{"class":180}," res.",[109,361,362],{"class":155},"json",[109,364,365],{"class":180},"()\n",[109,367,369],{"class":111,"line":368},11,[109,370,372],{"class":371},"sJ8bj","\u002F\u002F data.token is shown only in this response — store it now\n",[100,374,379],{"className":375,"code":376,"filename":377,"language":378,"meta":105,"style":105},"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\u002Fapi-tokens\",\n    headers={\"Authorization\": f\"Bearer {os.environ['SENDAI_API_KEY']}\"},\n    json={\"name\": \"orders-service\"},\n)\n\ndata = res.json()[\"data\"]\n# data[\"token\"] is shown only in this response — store it now\n","Python","python",[95,380,381,389,396,400,410,417,458,477,482,486,502],{"__ignoreMap":105},[109,382,383,386],{"class":111,"line":33},[109,384,385],{"class":117},"import",[109,387,388],{"class":180}," os\n",[109,390,391,393],{"class":111,"line":49},[109,392,385],{"class":117},[109,394,395],{"class":180}," requests\n",[109,397,398],{"class":111,"line":7},[109,399,337],{"emptyLinePlaceholder":336},[109,401,402,405,407],{"class":111,"line":21},[109,403,404],{"class":180},"res ",[109,406,354],{"class":117},[109,408,409],{"class":180}," requests.post(\n",[109,411,412,415],{"class":111,"line":38},[109,413,414],{"class":121},"    \"https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fapi-tokens\"",[109,416,248],{"class":180},[109,418,419,423,425,428,431,433,436,439,441,444,447,450,453,455],{"class":111,"line":298},[109,420,422],{"class":421},"s4XuR","    headers",[109,424,354],{"class":117},[109,426,427],{"class":180},"{",[109,429,430],{"class":121},"\"Authorization\"",[109,432,261],{"class":180},[109,434,435],{"class":117},"f",[109,437,438],{"class":121},"\"Bearer ",[109,440,427],{"class":159},[109,442,443],{"class":180},"os.environ[",[109,445,446],{"class":121},"'SENDAI_API_KEY'",[109,448,449],{"class":180},"]",[109,451,452],{"class":159},"}",[109,454,184],{"class":121},[109,456,457],{"class":180},"},\n",[109,459,460,463,465,467,470,472,475],{"class":111,"line":304},[109,461,462],{"class":421},"    json",[109,464,354],{"class":117},[109,466,427],{"class":180},[109,468,469],{"class":121},"\"name\"",[109,471,261],{"class":180},[109,473,474],{"class":121},"\"orders-service\"",[109,476,457],{"class":180},[109,478,479],{"class":111,"line":327},[109,480,481],{"class":180},")\n",[109,483,484],{"class":111,"line":333},[109,485,337],{"emptyLinePlaceholder":336},[109,487,488,491,493,496,499],{"class":111,"line":340},[109,489,490],{"class":180},"data ",[109,492,354],{"class":117},[109,494,495],{"class":180}," res.json()[",[109,497,498],{"class":121},"\"data\"",[109,500,501],{"class":180},"]\n",[109,503,504],{"class":111,"line":368},[109,505,506],{"class":371},"# data[\"token\"] is shown only in this response — store it now\n",[139,508,510],{"title":509},"Response",[100,511,515],{"className":512,"code":513,"filename":514,"language":362,"meta":105,"style":105},"language-json shiki shiki-themes github-light github-dark","{\n  \"status\": \"success\",\n  \"message\": \"api token created — save this token, it will not be shown again\",\n  \"data\": {\n    \"id\": \"9f2a4c8e-6b21-4d0f-a97b-5e8c1d2f6a3b\",\n    \"name\": \"orders-service\",\n    \"token\": \"sk_live_4c8e6b21d0f34a97b5e8c1d2f6a3b904\",\n    \"account_id\": \"2d6f4b8e-1a90-4e21-8b7d-3f1a5c2e9a0c\",\n    \"created_at\": \"2026-07-06T09:12:03Z\"\n  }\n}\n","201 Created",[95,516,517,522,534,546,554,566,577,589,601,611,616],{"__ignoreMap":105},[109,518,519],{"class":111,"line":33},[109,520,521],{"class":180},"{\n",[109,523,524,527,529,532],{"class":111,"line":49},[109,525,526],{"class":159},"  \"status\"",[109,528,261],{"class":180},[109,530,531],{"class":121},"\"success\"",[109,533,248],{"class":180},[109,535,536,539,541,544],{"class":111,"line":7},[109,537,538],{"class":159},"  \"message\"",[109,540,261],{"class":180},[109,542,543],{"class":121},"\"api token created — save this token, it will not be shown again\"",[109,545,248],{"class":180},[109,547,548,551],{"class":111,"line":21},[109,549,550],{"class":159},"  \"data\"",[109,552,553],{"class":180},": {\n",[109,555,556,559,561,564],{"class":111,"line":38},[109,557,558],{"class":159},"    \"id\"",[109,560,261],{"class":180},[109,562,563],{"class":121},"\"9f2a4c8e-6b21-4d0f-a97b-5e8c1d2f6a3b\"",[109,565,248],{"class":180},[109,567,568,571,573,575],{"class":111,"line":298},[109,569,570],{"class":159},"    \"name\"",[109,572,261],{"class":180},[109,574,474],{"class":121},[109,576,248],{"class":180},[109,578,579,582,584,587],{"class":111,"line":304},[109,580,581],{"class":159},"    \"token\"",[109,583,261],{"class":180},[109,585,586],{"class":121},"\"sk_live_4c8e6b21d0f34a97b5e8c1d2f6a3b904\"",[109,588,248],{"class":180},[109,590,591,594,596,599],{"class":111,"line":327},[109,592,593],{"class":159},"    \"account_id\"",[109,595,261],{"class":180},[109,597,598],{"class":121},"\"2d6f4b8e-1a90-4e21-8b7d-3f1a5c2e9a0c\"",[109,600,248],{"class":180},[109,602,603,606,608],{"class":111,"line":333},[109,604,605],{"class":159},"    \"created_at\"",[109,607,261],{"class":180},[109,609,610],{"class":121},"\"2026-07-06T09:12:03Z\"\n",[109,612,613],{"class":111,"line":340},[109,614,615],{"class":180},"  }\n",[109,617,618],{"class":111,"line":368},[109,619,620],{"class":180},"}\n",[86,622,623,626,627,630],{},[95,624,625],{},"data.id"," is what you pass to the revoke endpoint — keep it alongside the key. ",[95,628,629],{},"account_id","\ntells you which account the key authenticates as.",[632,633,634],"blockquote",{},[86,635,636,642],{},[90,637,638,641],{},[95,639,640],{},"token"," is returned exactly once."," It appears in this create response and nowhere else —\nSendai stores only a hash. Put it straight into your secret manager. If you lose it, you\ncannot recover it; revoke the key and create another.",[127,644,646],{"id":645},"use-it","Use it",[86,648,649],{},"Send the key as a bearer credential on every call:",[139,651,653,698,823],{"title":141,"label":652},"POST \u002Fapi\u002Fv1\u002Fsms",[100,654,656],{"className":145,"code":655,"filename":147,"language":148,"meta":105,"style":105},"curl -X POST https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fsms \\\n  -H \"Authorization: Bearer $SENDAI_API_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{ \"to\": \"263771000000\", \"from\": \"YOUR_SENDER_ID\", \"message\": \"Your code is 4821\" }'\n",[95,657,658,671,683,691],{"__ignoreMap":105},[109,659,660,662,664,666,669],{"class":111,"line":33},[109,661,156],{"class":155},[109,663,160],{"class":159},[109,665,163],{"class":121},[109,667,668],{"class":121}," https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fsms",[109,670,169],{"class":159},[109,672,673,675,677,679,681],{"class":111,"line":49},[109,674,174],{"class":159},[109,676,177],{"class":121},[109,678,181],{"class":180},[109,680,184],{"class":121},[109,682,169],{"class":159},[109,684,685,687,689],{"class":111,"line":7},[109,686,174],{"class":159},[109,688,193],{"class":121},[109,690,169],{"class":159},[109,692,693,695],{"class":111,"line":21},[109,694,200],{"class":159},[109,696,697],{"class":121}," '{ \"to\": \"263771000000\", \"from\": \"YOUR_SENDER_ID\", \"message\": \"Your code is 4821\" }'\n",[100,699,701],{"className":206,"code":700,"filename":208,"language":209,"meta":105,"style":105},"const res = await fetch('https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fsms', {\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',\n    from: 'YOUR_SENDER_ID',\n    message: 'Your code is 4821',\n  }),\n})\n",[95,702,703,722,730,734,756,766,770,783,793,803,813,818],{"__ignoreMap":105},[109,704,705,707,709,711,713,715,717,720],{"class":111,"line":33},[109,706,216],{"class":117},[109,708,219],{"class":159},[109,710,222],{"class":117},[109,712,225],{"class":117},[109,714,228],{"class":155},[109,716,231],{"class":180},[109,718,719],{"class":121},"'https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fsms'",[109,721,237],{"class":180},[109,723,724,726,728],{"class":111,"line":49},[109,725,242],{"class":180},[109,727,245],{"class":121},[109,729,248],{"class":180},[109,731,732],{"class":111,"line":7},[109,733,253],{"class":180},[109,735,736,738,740,742,744,746,748,750,752,754],{"class":111,"line":21},[109,737,258],{"class":121},[109,739,261],{"class":180},[109,741,264],{"class":121},[109,743,267],{"class":180},[109,745,270],{"class":121},[109,747,273],{"class":180},[109,749,270],{"class":121},[109,751,278],{"class":159},[109,753,281],{"class":121},[109,755,248],{"class":180},[109,757,758,760,762,764],{"class":111,"line":38},[109,759,288],{"class":121},[109,761,261],{"class":180},[109,763,293],{"class":121},[109,765,248],{"class":180},[109,767,768],{"class":111,"line":298},[109,769,301],{"class":180},[109,771,772,774,776,778,780],{"class":111,"line":304},[109,773,307],{"class":180},[109,775,310],{"class":159},[109,777,270],{"class":180},[109,779,315],{"class":155},[109,781,782],{"class":180},"({\n",[109,784,785,788,791],{"class":111,"line":327},[109,786,787],{"class":180},"    to: ",[109,789,790],{"class":121},"'263771000000'",[109,792,248],{"class":180},[109,794,795,798,801],{"class":111,"line":333},[109,796,797],{"class":180},"    from: ",[109,799,800],{"class":121},"'YOUR_SENDER_ID'",[109,802,248],{"class":180},[109,804,805,808,811],{"class":111,"line":340},[109,806,807],{"class":180},"    message: ",[109,809,810],{"class":121},"'Your code is 4821'",[109,812,248],{"class":180},[109,814,815],{"class":111,"line":368},[109,816,817],{"class":180},"  }),\n",[109,819,821],{"class":111,"line":820},12,[109,822,330],{"class":180},[100,824,826],{"className":375,"code":825,"filename":377,"language":378,"meta":105,"style":105},"import os\nimport requests\n\nres = requests.post(\n    \"https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fsms\",\n    headers={\"Authorization\": f\"Bearer {os.environ['SENDAI_API_KEY']}\"},\n    json={\n        \"to\": \"263771000000\",\n        \"from\": \"YOUR_SENDER_ID\",\n        \"message\": \"Your code is 4821\",\n    },\n)\n",[95,827,828,834,840,844,852,859,889,897,909,921,933,938],{"__ignoreMap":105},[109,829,830,832],{"class":111,"line":33},[109,831,385],{"class":117},[109,833,388],{"class":180},[109,835,836,838],{"class":111,"line":49},[109,837,385],{"class":117},[109,839,395],{"class":180},[109,841,842],{"class":111,"line":7},[109,843,337],{"emptyLinePlaceholder":336},[109,845,846,848,850],{"class":111,"line":21},[109,847,404],{"class":180},[109,849,354],{"class":117},[109,851,409],{"class":180},[109,853,854,857],{"class":111,"line":38},[109,855,856],{"class":121},"    \"https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fsms\"",[109,858,248],{"class":180},[109,860,861,863,865,867,869,871,873,875,877,879,881,883,885,887],{"class":111,"line":298},[109,862,422],{"class":421},[109,864,354],{"class":117},[109,866,427],{"class":180},[109,868,430],{"class":121},[109,870,261],{"class":180},[109,872,435],{"class":117},[109,874,438],{"class":121},[109,876,427],{"class":159},[109,878,443],{"class":180},[109,880,446],{"class":121},[109,882,449],{"class":180},[109,884,452],{"class":159},[109,886,184],{"class":121},[109,888,457],{"class":180},[109,890,891,893,895],{"class":111,"line":304},[109,892,462],{"class":421},[109,894,354],{"class":117},[109,896,521],{"class":180},[109,898,899,902,904,907],{"class":111,"line":327},[109,900,901],{"class":121},"        \"to\"",[109,903,261],{"class":180},[109,905,906],{"class":121},"\"263771000000\"",[109,908,248],{"class":180},[109,910,911,914,916,919],{"class":111,"line":333},[109,912,913],{"class":121},"        \"from\"",[109,915,261],{"class":180},[109,917,918],{"class":121},"\"YOUR_SENDER_ID\"",[109,920,248],{"class":180},[109,922,923,926,928,931],{"class":111,"line":340},[109,924,925],{"class":121},"        \"message\"",[109,927,261],{"class":180},[109,929,930],{"class":121},"\"Your code is 4821\"",[109,932,248],{"class":180},[109,934,935],{"class":111,"line":368},[109,936,937],{"class":180},"    },\n",[109,939,940],{"class":111,"line":820},[109,941,481],{"class":180},[86,943,944,945,118],{},"A missing, malformed, or revoked key returns ",[95,946,947],{},"401",[139,949,950],{"title":509},[100,951,954],{"className":512,"code":952,"filename":953,"language":362,"meta":105,"style":105},"{\n  \"status\": \"error\",\n  \"message\": \"missing authentication\",\n  \"error\": { \"code\": \"UNAUTHORIZED\", \"description\": \"missing authentication\" }\n}\n","401 Unauthorized",[95,955,956,960,971,982,1011],{"__ignoreMap":105},[109,957,958],{"class":111,"line":33},[109,959,521],{"class":180},[109,961,962,964,966,969],{"class":111,"line":49},[109,963,526],{"class":159},[109,965,261],{"class":180},[109,967,968],{"class":121},"\"error\"",[109,970,248],{"class":180},[109,972,973,975,977,980],{"class":111,"line":7},[109,974,538],{"class":159},[109,976,261],{"class":180},[109,978,979],{"class":121},"\"missing authentication\"",[109,981,248],{"class":180},[109,983,984,987,990,993,995,998,1001,1004,1006,1008],{"class":111,"line":21},[109,985,986],{"class":159},"  \"error\"",[109,988,989],{"class":180},": { ",[109,991,992],{"class":159},"\"code\"",[109,994,261],{"class":180},[109,996,997],{"class":121},"\"UNAUTHORIZED\"",[109,999,1000],{"class":180},", ",[109,1002,1003],{"class":159},"\"description\"",[109,1005,261],{"class":180},[109,1007,979],{"class":121},[109,1009,1010],{"class":180}," }\n",[109,1012,1013],{"class":111,"line":38},[109,1014,620],{"class":180},[127,1016,1018],{"id":1017},"list-your-keys","List your keys",[86,1020,1021],{},"Listing lets you audit which keys exist and what each is for:",[139,1023,1025,1049,1136],{"title":141,"label":1024},"GET \u002Fapi\u002Fv1\u002Fapi-tokens",[100,1026,1028],{"className":145,"code":1027,"filename":147,"language":148,"meta":105,"style":105},"curl https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fapi-tokens \\\n  -H \"Authorization: Bearer $SENDAI_API_KEY\"\n",[95,1029,1030,1038],{"__ignoreMap":105},[109,1031,1032,1034,1036],{"class":111,"line":33},[109,1033,156],{"class":155},[109,1035,166],{"class":121},[109,1037,169],{"class":159},[109,1039,1040,1042,1044,1046],{"class":111,"line":49},[109,1041,174],{"class":159},[109,1043,177],{"class":121},[109,1045,181],{"class":180},[109,1047,1048],{"class":121},"\"\n",[100,1050,1052],{"className":206,"code":1051,"filename":208,"language":209,"meta":105,"style":105},"const res = await fetch('https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fapi-tokens', {\n  headers: { 'Authorization': `Bearer ${process.env.SENDAI_API_KEY}` },\n})\n\nconst { data: keys } = await res.json() \u002F\u002F PascalCase fields — ID, Name, Active…\n",[95,1053,1054,1072,1099,1103,1107],{"__ignoreMap":105},[109,1055,1056,1058,1060,1062,1064,1066,1068,1070],{"class":111,"line":33},[109,1057,216],{"class":117},[109,1059,219],{"class":159},[109,1061,222],{"class":117},[109,1063,225],{"class":117},[109,1065,228],{"class":155},[109,1067,231],{"class":180},[109,1069,234],{"class":121},[109,1071,237],{"class":180},[109,1073,1074,1077,1080,1082,1084,1086,1088,1090,1092,1094,1096],{"class":111,"line":49},[109,1075,1076],{"class":180},"  headers: { ",[109,1078,1079],{"class":121},"'Authorization'",[109,1081,261],{"class":180},[109,1083,264],{"class":121},[109,1085,267],{"class":180},[109,1087,270],{"class":121},[109,1089,273],{"class":180},[109,1091,270],{"class":121},[109,1093,278],{"class":159},[109,1095,281],{"class":121},[109,1097,1098],{"class":180}," },\n",[109,1100,1101],{"class":111,"line":7},[109,1102,330],{"class":180},[109,1104,1105],{"class":111,"line":21},[109,1106,337],{"emptyLinePlaceholder":336},[109,1108,1109,1111,1113,1115,1117,1120,1122,1124,1126,1128,1130,1133],{"class":111,"line":38},[109,1110,216],{"class":117},[109,1112,345],{"class":180},[109,1114,348],{"class":421},[109,1116,261],{"class":180},[109,1118,1119],{"class":159},"keys",[109,1121,351],{"class":180},[109,1123,354],{"class":117},[109,1125,225],{"class":117},[109,1127,359],{"class":180},[109,1129,362],{"class":155},[109,1131,1132],{"class":180},"() ",[109,1134,1135],{"class":371},"\u002F\u002F PascalCase fields — ID, Name, Active…\n",[100,1137,1139],{"className":375,"code":1138,"filename":377,"language":378,"meta":105,"style":105},"import os\nimport requests\n\nres = requests.get(\n    \"https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fapi-tokens\",\n    headers={\"Authorization\": f\"Bearer {os.environ['SENDAI_API_KEY']}\"},\n)\n\nkeys = res.json()[\"data\"]  # PascalCase fields — ID, Name, Active…\n",[95,1140,1141,1147,1153,1157,1166,1172,1202,1206,1210],{"__ignoreMap":105},[109,1142,1143,1145],{"class":111,"line":33},[109,1144,385],{"class":117},[109,1146,388],{"class":180},[109,1148,1149,1151],{"class":111,"line":49},[109,1150,385],{"class":117},[109,1152,395],{"class":180},[109,1154,1155],{"class":111,"line":7},[109,1156,337],{"emptyLinePlaceholder":336},[109,1158,1159,1161,1163],{"class":111,"line":21},[109,1160,404],{"class":180},[109,1162,354],{"class":117},[109,1164,1165],{"class":180}," requests.get(\n",[109,1167,1168,1170],{"class":111,"line":38},[109,1169,414],{"class":121},[109,1171,248],{"class":180},[109,1173,1174,1176,1178,1180,1182,1184,1186,1188,1190,1192,1194,1196,1198,1200],{"class":111,"line":298},[109,1175,422],{"class":421},[109,1177,354],{"class":117},[109,1179,427],{"class":180},[109,1181,430],{"class":121},[109,1183,261],{"class":180},[109,1185,435],{"class":117},[109,1187,438],{"class":121},[109,1189,427],{"class":159},[109,1191,443],{"class":180},[109,1193,446],{"class":121},[109,1195,449],{"class":180},[109,1197,452],{"class":159},[109,1199,184],{"class":121},[109,1201,457],{"class":180},[109,1203,1204],{"class":111,"line":304},[109,1205,481],{"class":180},[109,1207,1208],{"class":111,"line":327},[109,1209,337],{"emptyLinePlaceholder":336},[109,1211,1212,1215,1217,1219,1221,1224],{"class":111,"line":333},[109,1213,1214],{"class":180},"keys ",[109,1216,354],{"class":117},[109,1218,495],{"class":180},[109,1220,498],{"class":121},[109,1222,1223],{"class":180},"]  ",[109,1225,1226],{"class":371},"# PascalCase fields — ID, Name, Active…\n",[139,1228,1229],{"title":509},[100,1230,1233],{"className":512,"code":1231,"filename":1232,"language":362,"meta":105,"style":105},"{\n  \"status\": \"success\",\n  \"message\": \"\",\n  \"data\": [\n    {\n      \"ID\": \"9f2a4c8e-6b21-4d0f-a97b-5e8c1d2f6a3b\",\n      \"CreatedAt\": \"2026-07-06T09:12:03Z\",\n      \"Name\": \"orders-service\",\n      \"Active\": true,\n      \"LastUsedAt\": \"2026-08-06T11:04:19Z\"\n    }\n  ]\n}\n","200 OK",[95,1234,1235,1239,1249,1260,1267,1272,1283,1295,1306,1318,1328,1333,1338],{"__ignoreMap":105},[109,1236,1237],{"class":111,"line":33},[109,1238,521],{"class":180},[109,1240,1241,1243,1245,1247],{"class":111,"line":49},[109,1242,526],{"class":159},[109,1244,261],{"class":180},[109,1246,531],{"class":121},[109,1248,248],{"class":180},[109,1250,1251,1253,1255,1258],{"class":111,"line":7},[109,1252,538],{"class":159},[109,1254,261],{"class":180},[109,1256,1257],{"class":121},"\"\"",[109,1259,248],{"class":180},[109,1261,1262,1264],{"class":111,"line":21},[109,1263,550],{"class":159},[109,1265,1266],{"class":180},": [\n",[109,1268,1269],{"class":111,"line":38},[109,1270,1271],{"class":180},"    {\n",[109,1273,1274,1277,1279,1281],{"class":111,"line":298},[109,1275,1276],{"class":159},"      \"ID\"",[109,1278,261],{"class":180},[109,1280,563],{"class":121},[109,1282,248],{"class":180},[109,1284,1285,1288,1290,1293],{"class":111,"line":304},[109,1286,1287],{"class":159},"      \"CreatedAt\"",[109,1289,261],{"class":180},[109,1291,1292],{"class":121},"\"2026-07-06T09:12:03Z\"",[109,1294,248],{"class":180},[109,1296,1297,1300,1302,1304],{"class":111,"line":327},[109,1298,1299],{"class":159},"      \"Name\"",[109,1301,261],{"class":180},[109,1303,474],{"class":121},[109,1305,248],{"class":180},[109,1307,1308,1311,1313,1316],{"class":111,"line":333},[109,1309,1310],{"class":159},"      \"Active\"",[109,1312,261],{"class":180},[109,1314,1315],{"class":159},"true",[109,1317,248],{"class":180},[109,1319,1320,1323,1325],{"class":111,"line":340},[109,1321,1322],{"class":159},"      \"LastUsedAt\"",[109,1324,261],{"class":180},[109,1326,1327],{"class":121},"\"2026-08-06T11:04:19Z\"\n",[109,1329,1330],{"class":111,"line":368},[109,1331,1332],{"class":180},"    }\n",[109,1334,1335],{"class":111,"line":820},[109,1336,1337],{"class":180},"  ]\n",[109,1339,1341],{"class":111,"line":1340},13,[109,1342,620],{"class":180},[632,1344,1345],{},[86,1346,1347,1350,1351,1000,1354,1000,1357,1000,1360,1363,1364,1367],{},[90,1348,1349],{},"Field names on this endpoint are PascalCase",", not snake_case like the rest of the API —\nit serialises the internal record directly. Read ",[95,1352,1353],{},"ID",[95,1355,1356],{},"Name",[95,1358,1359],{},"Active",[95,1361,1362],{},"CreatedAt"," and\n",[95,1365,1366],{},"LastUsedAt","; the response carries a few storage columns beyond these, which you should\ntreat as unstable and not build against.",[86,1369,1370,1372,1373,1376],{},[95,1371,1366],{}," is the useful one for cleanup: a key that has never been used is ",[95,1374,1375],{},"null",", and a\nkey untouched for months is usually one you can revoke.",[127,1378,1380],{"id":1379},"revoke-a-key","Revoke a key",[86,1382,1383,1384,1386,1387,1389],{},"Revocation takes effect immediately — the next request using that key gets a ",[95,1385,947],{},". Pass the\n",[95,1388,1353],{}," from the create or list response:",[139,1391,1393,1422,1499],{"title":141,"label":1392},"DELETE \u002Fapi\u002Fv1\u002Fapi-tokens\u002F{id}",[100,1394,1396],{"className":145,"code":1395,"filename":147,"language":148,"meta":105,"style":105},"curl -X DELETE https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fapi-tokens\u002F9f2a4c8e-6b21-4d0f-a97b-5e8c1d2f6a3b \\\n  -H \"Authorization: Bearer $SENDAI_API_KEY\"\n",[95,1397,1398,1412],{"__ignoreMap":105},[109,1399,1400,1402,1404,1407,1410],{"class":111,"line":33},[109,1401,156],{"class":155},[109,1403,160],{"class":159},[109,1405,1406],{"class":121}," DELETE",[109,1408,1409],{"class":121}," https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fapi-tokens\u002F9f2a4c8e-6b21-4d0f-a97b-5e8c1d2f6a3b",[109,1411,169],{"class":159},[109,1413,1414,1416,1418,1420],{"class":111,"line":49},[109,1415,174],{"class":159},[109,1417,177],{"class":121},[109,1419,181],{"class":180},[109,1421,1048],{"class":121},[100,1423,1425],{"className":206,"code":1424,"filename":208,"language":209,"meta":105,"style":105},"const id = '9f2a4c8e-6b21-4d0f-a97b-5e8c1d2f6a3b'\n\nawait fetch(`https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fapi-tokens\u002F${id}`, {\n  method: 'DELETE',\n  headers: { 'Authorization': `Bearer ${process.env.SENDAI_API_KEY}` },\n})\n",[95,1426,1427,1439,1443,1462,1471,1495],{"__ignoreMap":105},[109,1428,1429,1431,1434,1436],{"class":111,"line":33},[109,1430,216],{"class":117},[109,1432,1433],{"class":159}," id",[109,1435,222],{"class":117},[109,1437,1438],{"class":121}," '9f2a4c8e-6b21-4d0f-a97b-5e8c1d2f6a3b'\n",[109,1440,1441],{"class":111,"line":49},[109,1442,337],{"emptyLinePlaceholder":336},[109,1444,1445,1448,1450,1452,1455,1458,1460],{"class":111,"line":7},[109,1446,1447],{"class":117},"await",[109,1449,228],{"class":155},[109,1451,231],{"class":180},[109,1453,1454],{"class":121},"`https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fapi-tokens\u002F${",[109,1456,1457],{"class":180},"id",[109,1459,281],{"class":121},[109,1461,237],{"class":180},[109,1463,1464,1466,1469],{"class":111,"line":21},[109,1465,242],{"class":180},[109,1467,1468],{"class":121},"'DELETE'",[109,1470,248],{"class":180},[109,1472,1473,1475,1477,1479,1481,1483,1485,1487,1489,1491,1493],{"class":111,"line":38},[109,1474,1076],{"class":180},[109,1476,1079],{"class":121},[109,1478,261],{"class":180},[109,1480,264],{"class":121},[109,1482,267],{"class":180},[109,1484,270],{"class":121},[109,1486,273],{"class":180},[109,1488,270],{"class":121},[109,1490,278],{"class":159},[109,1492,281],{"class":121},[109,1494,1098],{"class":180},[109,1496,1497],{"class":111,"line":298},[109,1498,330],{"class":180},[100,1500,1502],{"className":375,"code":1501,"filename":377,"language":378,"meta":105,"style":105},"import os\nimport requests\n\nkey_id = \"9f2a4c8e-6b21-4d0f-a97b-5e8c1d2f6a3b\"\n\nrequests.delete(\n    f\"https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fapi-tokens\u002F{key_id}\",\n    headers={\"Authorization\": f\"Bearer {os.environ['SENDAI_API_KEY']}\"},\n)\n",[95,1503,1504,1510,1516,1520,1530,1534,1539,1558,1588],{"__ignoreMap":105},[109,1505,1506,1508],{"class":111,"line":33},[109,1507,385],{"class":117},[109,1509,388],{"class":180},[109,1511,1512,1514],{"class":111,"line":49},[109,1513,385],{"class":117},[109,1515,395],{"class":180},[109,1517,1518],{"class":111,"line":7},[109,1519,337],{"emptyLinePlaceholder":336},[109,1521,1522,1525,1527],{"class":111,"line":21},[109,1523,1524],{"class":180},"key_id ",[109,1526,354],{"class":117},[109,1528,1529],{"class":121}," \"9f2a4c8e-6b21-4d0f-a97b-5e8c1d2f6a3b\"\n",[109,1531,1532],{"class":111,"line":38},[109,1533,337],{"emptyLinePlaceholder":336},[109,1535,1536],{"class":111,"line":298},[109,1537,1538],{"class":180},"requests.delete(\n",[109,1540,1541,1544,1547,1549,1552,1554,1556],{"class":111,"line":304},[109,1542,1543],{"class":117},"    f",[109,1545,1546],{"class":121},"\"https:\u002F\u002Fapi.sendai.co.zw\u002Fapi\u002Fv1\u002Fapi-tokens\u002F",[109,1548,427],{"class":159},[109,1550,1551],{"class":180},"key_id",[109,1553,452],{"class":159},[109,1555,184],{"class":121},[109,1557,248],{"class":180},[109,1559,1560,1562,1564,1566,1568,1570,1572,1574,1576,1578,1580,1582,1584,1586],{"class":111,"line":327},[109,1561,422],{"class":421},[109,1563,354],{"class":117},[109,1565,427],{"class":180},[109,1567,430],{"class":121},[109,1569,261],{"class":180},[109,1571,435],{"class":117},[109,1573,438],{"class":121},[109,1575,427],{"class":159},[109,1577,443],{"class":180},[109,1579,446],{"class":121},[109,1581,449],{"class":180},[109,1583,452],{"class":159},[109,1585,184],{"class":121},[109,1587,457],{"class":180},[109,1589,1590],{"class":111,"line":333},[109,1591,481],{"class":180},[139,1593,1594],{"title":509},[100,1595,1597],{"className":512,"code":1596,"filename":1232,"language":362,"meta":105,"style":105},"{ \"status\": \"success\", \"message\": \"api token revoked\" }\n",[95,1598,1599],{"__ignoreMap":105},[109,1600,1601,1604,1607,1609,1611,1613,1616,1618,1621],{"class":111,"line":33},[109,1602,1603],{"class":180},"{ ",[109,1605,1606],{"class":159},"\"status\"",[109,1608,261],{"class":180},[109,1610,531],{"class":121},[109,1612,1000],{"class":180},[109,1614,1615],{"class":159},"\"message\"",[109,1617,261],{"class":180},[109,1619,1620],{"class":121},"\"api token revoked\"",[109,1622,1010],{"class":180},[86,1624,1625,1626,1629,1630,1633,1634,1637,1638,1641],{},"A malformed id returns ",[95,1627,1628],{},"400 invalid token id",". Note that revoking an id that does not exist\ndoes ",[90,1631,1632],{},"not"," return ",[95,1635,1636],{},"404"," — treat a ",[95,1639,1640],{},"200"," as \"this key is now not valid\" rather than as proof\nthe key existed.",[127,1643,1645],{"id":1644},"rotating-without-downtime","Rotating without downtime",[86,1647,1648],{},"Because a key is valid until revoked, you can overlap the old and the new and never drop a\nmessage:",[1650,1651,1652,1659,1665,1671],"ol",{},[1653,1654,1655,1658],"li",{},[90,1656,1657],{},"Create"," the replacement key.",[1653,1660,1661,1664],{},[90,1662,1663],{},"Deploy"," it to the service, alongside or in place of the old one.",[1653,1666,1667,1670],{},[90,1668,1669],{},"Confirm"," traffic has moved — new sends succeed with the new key.",[1653,1672,1673,1676],{},[90,1674,1675],{},"Revoke"," the old key.",[86,1678,1679],{},"Revoking before step 3 is what causes an outage. Keep the overlap short, but do keep it.",[127,1681,1683],{"id":1682},"handling-keys-safely","Handling keys safely",[1685,1686,1687,1693,1699,1708],"ul",{},[1653,1688,1689,1692],{},[90,1690,1691],{},"One key per service."," Separate keys for your orders service, your marketing job, and\nyour staging environment mean you can revoke one without touching the others.",[1653,1694,1695,1698],{},[90,1696,1697],{},"Never commit a key."," Keep them in environment variables or a secret manager, not in\nsource control, client-side JavaScript, or a mobile app — anything shipped to a user's\ndevice can be read by that user.",[1653,1700,1701,1707],{},[90,1702,1703,1704,1706],{},"Never log the ",[95,1705,97],{}," header."," Redact it in request logs and error reporters.",[1653,1709,1710,1713],{},[90,1711,1712],{},"Rotate on a cadence",", and immediately if a key is exposed.",[127,1715,1717],{"id":1716},"next-steps","Next steps",[1685,1719,1720,1726,1731,1736],{},[1653,1721,1722,1723],{},"Send your first message → ",[1724,1725,74],"a",{"href":73},[1653,1727,1728,1729],{},"Send to many recipients at once → ",[1724,1730,68],{"href":67},[1653,1732,1733,1734],{},"The token endpoints in full → ",[1724,1735,6],{"href":5},[1653,1737,1738,1739],{},"Hand a key to an AI agent → ",[1724,1740,1741],{"href":70},"AI agents",[1743,1744,1745],"style",{},"html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}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 .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 .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}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":105,"searchDepth":49,"depth":49,"links":1747},[1748,1749,1750,1751,1752,1753,1754],{"id":129,"depth":49,"text":130},{"id":645,"depth":49,"text":646},{"id":1017,"depth":49,"text":1018},{"id":1379,"depth":49,"text":1380},{"id":1644,"depth":49,"text":1645},{"id":1682,"depth":49,"text":1683},{"id":1716,"depth":49,"text":1717},{"title":65,"description":80},"guides\u002Fauthentication","md",{},1786390037512]