[{"data":1,"prerenderedAt":164},["ShallowReactive",2],{"pseo:tutorials:post-status:python":3,"highlight:tutorial:post-status:python":151},{"ban_risk":4,"ban_risk_note":5,"deploy_targets":6,"errors":11,"faqs":21,"feature":32,"full_script":36,"gotchas":40,"intro_note":46,"language":47,"pitfalls":51,"prerequisites":55,"related":58,"seo":88,"siblings":104,"step_summary":111,"steps":112,"tier":142,"url":98,"webhook_receiver":143},"medium","Status posts are seen only by people who already saved your number, which makes them gentler than messaging, but they are still activity on the linked number and they still count toward the pacing budget. Posting a dozen times a day is what a spam account looks like; once or twice is what a shop looks like.",[7,8,9,10],"Google Cloud Run (container, scale to zero, one revision per deploy)","Render background worker for the sender, Render web service for the webhook receiver","A 1 GB VPS with systemd for the worker and Caddy in front of the FastAPI receiver","AWS Lambda + API Gateway for the webhook receiver only (the sender needs a long-lived process for queue spacing)",[12,15,18],{"title":13,"url":14},"payload_too_large (413)","\u002Fdocs\u002Ferrors\u002Fpayload-too-large\u002F",{"title":16,"url":17},"unsupported_media_type (415)","\u002Fdocs\u002Ferrors\u002Funsupported-media-type\u002F",{"title":19,"url":20},"channel_locked (403)","\u002Fdocs\u002Ferrors\u002Fchannel-locked\u002F",[22,26,29],{"a":23,"q":24,"source":25},"People who have saved your number in their contacts and have not restricted status from you. There is no subscriber list and no way to add someone, so growing reach means getting more people to save your number - which is a marketing problem rather than an API one.","Who actually sees my status?","features.json",{"a":27,"q":28,"source":25},"Not inside WhatsApp, but that is exactly what the API is for: run a scheduler on your side and call the endpoint at the moment you want the post to appear. Since statuses expire after a day, posting at the right hour matters more here than for almost anything else.","Can I schedule status posts?",{"a":30,"q":31,"source":25},"It is activity on the linked number and is paced through the same queue, so treat it as part of your daily budget rather than as free. It does not consume a per-recipient send the way a broadcast would, which is part of why it is an efficient way to reach saved contacts.","Does posting status count as sending?",{"name":33,"slug":34,"url":35},"Post Status","post-status","\u002Fwhatsapp-api\u002Fpost-status\u002F",{"code":37,"filename":38,"lang":39},"\"\"\"Post Status with the Wapito WhatsApp API.\n\nPost a text card, or upload media once and post it as an image, video or voice status with a caption that carries the detail.\n\nRun it with:\n    export WAPITO_TOKEN=\"wpt_...\"\n    python post-status.py\n\"\"\"\nimport os\n\nimport requests\n\nBASE_URL = \"https:\u002F\u002Fapi.wapito.com\u002Fv1\"\nTOKEN = os.environ[\"WAPITO_TOKEN\"]\n\n# --- Post a text card ---\nurl = BASE_URL + \"\u002Fstories\u002Ftext\"\n\npayload = {\n    \"body\": \"Workshop closed Friday for stocktake. Orders ship Monday.\",\n    \"background_color\": \"#0B7F5C\",\n    \"font\": 2,\n    \"contacts\": [\"+15551234567\", \"+15559876543\"]\n}\nheaders = {\n    \"Authorization\": \"Bearer \" + TOKEN,\n    \"Content-Type\": \"application\u002Fjson\"\n}\n\nresponse = requests.post(url, json=payload, headers=headers)\n\nprint(response.json())\n\n# --- Upload the image or video ---\nurl = BASE_URL + \"\u002Fmedia\"\n\npayload = {\n    \"data\": \"data:image\u002Fjpeg;base64,\u002F9j\u002F4AAQSkZJRgABAQEASABIAAD\u002F2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD…\",\n    \"filename\": \"new-colours.jpg\"\n}\nheaders = {\n    \"Authorization\": \"Bearer \" + TOKEN,\n    \"Content-Type\": \"application\u002Fjson\"\n}\n\nresponse = requests.post(url, json=payload, headers=headers)\n\nprint(response.json())\n\n# --- Post the media status ---\nurl = BASE_URL + \"\u002Fstories\u002Fmedia\"\n\npayload = {\n    \"media\": \"https:\u002F\u002Facme.example\u002Fstatus\u002Fnew-colours.jpg\",\n    \"caption\": \"New colours, same price.\",\n    \"contacts\": [\"+15551234567\"]\n}\nheaders = {\n    \"Authorization\": \"Bearer \" + TOKEN,\n    \"Content-Type\": \"application\u002Fjson\"\n}\n\nresponse = requests.post(url, json=payload, headers=headers)\n\nprint(response.json())\n\n# --- Post a voice status ---\nurl = BASE_URL + \"\u002Fstories\u002Faudio\"\n\npayload = {\n    \"media\": \"https:\u002F\u002Facme.example\u002Fstatus\u002Fmonday-update.m4a\",\n    \"background_color\": \"#1D2B3A\"\n}\nheaders = {\n    \"Authorization\": \"Bearer \" + TOKEN,\n    \"Content-Type\": \"application\u002Fjson\"\n}\n\nresponse = requests.post(url, json=payload, headers=headers)\n\nprint(response.json())\n\n","post-status.py","python",[41,42,43,44,45],"requests does not raise on a 4xx by itself. Call response.raise_for_status() or check response.ok, otherwise a 429 send_rate_limited silently looks like a successful send and your loop keeps hammering the queue.","json= and data= are not interchangeable. Pass json={...} so requests sets Content-Type: application\u002Fjson and encodes UTF-8 for you; data= with a dict sends form encoding and the API answers 400 invalid_request.","The default requests timeout is None, which means a stalled connection hangs your worker forever. Always pass timeout=(5, 30) and treat a read timeout as \"maybe delivered\" - re-check with the message id before you send again.","A group id such as 120363000000000000@g.us is a string, not a number. Building it with an f-string from an int drops the precision and you get 404 not_found.","Emoji and accented text need no extra work in Python 3, but reading a CSV of numbers with the default encoding on Windows will mangle them - open files with encoding=\"utf-8\".","Posting a status from Python is four requests.post calls of the same shape with different bodies; the only file handling is the upload, which is a base64 data URI built from pathlib and base64. A cron job that runs once a day fits well, and the same media id can go to a status and to a channel in one run.",{"family":48,"name":49,"slug":39,"url":50},"scripting","Python","\u002Fwhatsapp-bot\u002Fpython\u002F",[52,53,54],"Reading a large video into memory with read_bytes and base64-encoding it inside a JSON string can exceed the plan's size cap and your worker's memory at the same time; keep status assets small and check the file size first.","mimetypes.guess_type returns (None, None) for an unknown extension, and formatting None into the data URI sends data:None;base64 which the API answers with 400 invalid_request; fall back to an explicit mime.","A cron job that runs the script at midnight UTC posts the status at the wrong local time for most of the world; schedule it in the number's timezone.",[56,57],"pip install requests","os.environ[\"WAPITO_TOKEN\"]",{"language_hub":50,"operations":59,"pillar":35,"same_language_features":72},[60,63,66,69],{"title":61,"url":62},"POST \u002Fstories\u002Ftext","\u002Fdocs\u002Fapi\u002Fstories\u002Fpost-text-story\u002F",{"title":64,"url":65},"POST \u002Fmedia","\u002Fdocs\u002Fapi\u002Fmedia\u002Fupload-media\u002F",{"title":67,"url":68},"POST \u002Fstories\u002Fmedia","\u002Fdocs\u002Fapi\u002Fstories\u002Fpost-media-story\u002F",{"title":70,"url":71},"POST \u002Fstories\u002Faudio","\u002Fdocs\u002Fapi\u002Fstories\u002Fpost-audio-story\u002F",[73,76,79,82,85],{"title":74,"url":75},"Create Group","\u002Fwhatsapp-api\u002Fcreate-group\u002Fpython\u002F",{"title":77,"url":78},"Group Participants","\u002Fwhatsapp-api\u002Fgroup-participants\u002Fpython\u002F",{"title":80,"url":81},"Group Admins","\u002Fwhatsapp-api\u002Fgroup-admins\u002Fpython\u002F",{"title":83,"url":84},"Group Invite Link","\u002Fwhatsapp-api\u002Fgroup-invite-link\u002Fpython\u002F",{"title":86,"url":87},"Group Settings","\u002Fwhatsapp-api\u002Fgroup-settings\u002Fpython\u002F",{"breadcrumb":89,"canonical":99,"description":100,"h1":101,"lastmod":102,"title":103},[90,93,96,97],{"name":91,"url":92},"Home","\u002F",{"name":94,"url":95},"WhatsApp API","\u002Fwhatsapp-api\u002F",{"name":33,"url":35},{"name":49,"url":98},"\u002Fwhatsapp-api\u002Fpost-status\u002Fpython\u002F","https:\u002F\u002Fwapito.com\u002Fwhatsapp-api\u002Fpost-status\u002Fpython\u002F","How to post a status update in Python with the Wapito WhatsApp API. 4 steps with runnable code, a FastAPI webhook receiver and the errors to expect.","How to post a status update in Python with the Wapito WhatsApp API","2026-09-16","Post a Status in Python (WhatsApp API Tutorial) | Wapito",[105,108],{"title":106,"url":107},"Node.js","\u002Fwhatsapp-api\u002Fpost-status\u002Fnodejs\u002F",{"title":109,"url":110},"PHP","\u002Fwhatsapp-api\u002Fpost-status\u002Fphp\u002F","Post a text card, or upload media once and post it as an image, video or voice status with a caption that carries the detail.",[113,121,128,135],{"body":114,"note":115,"operationId":116,"operation_url":62,"snippet":117,"title":119,"webhook":120},"A text status is a short line on a coloured background. Keep it under a couple of dozen words: the card is read in a second by someone tapping through, not studied.","In Python post a text card with requests.post(url, json={\"text\": ..., \"background\": ...}) and keep the returned id; there is nothing to encode by hand because requests serialises the dict. Keep the text short in code with a length check, since a card longer than a couple of dozen words is unreadable.","postTextStory",{"code":118,"lang":39},"import requests\n\nurl = \"https:\u002F\u002Fapi.wapito.com\u002Fv1\u002Fstories\u002Ftext\"\n\npayload = {\n    \"body\": \"Workshop closed Friday for stocktake. Orders ship Monday.\",\n    \"background_color\": \"#0B7F5C\",\n    \"font\": 2,\n    \"contacts\": [\"+15551234567\", \"+15559876543\"]\n}\nheaders = {\n    \"Authorization\": \"Bearer wpt_YOUR_TOKEN\",\n    \"Content-Type\": \"application\u002Fjson\"\n}\n\nresponse = requests.post(url, json=payload, headers=headers)\n\nprint(response.json())","Post a text card",null,{"body":122,"note":123,"operationId":124,"operation_url":65,"snippet":125,"title":127,"webhook":120},"Upload once and reuse the media id if you post the same asset to status and to a channel. Portrait assets fill the screen; landscape ones are letterboxed and look like an afterthought.","In Python upload by building the data URI from base64.b64encode(Path(path).read_bytes()).decode() with the mime from mimetypes.guess_type, and requests.post it as a JSON body. The returned dict carries the media id, which you can hold in a variable and reuse for a channel post in the same run.","uploadMedia",{"code":126,"lang":39},"import requests\n\nurl = \"https:\u002F\u002Fapi.wapito.com\u002Fv1\u002Fmedia\"\n\npayload = {\n    \"data\": \"data:image\u002Fjpeg;base64,\u002F9j\u002F4AAQSkZJRgABAQEASABIAAD\u002F2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD…\",\n    \"filename\": \"new-colours.jpg\"\n}\nheaders = {\n    \"Authorization\": \"Bearer wpt_YOUR_TOKEN\",\n    \"Content-Type\": \"application\u002Fjson\"\n}\n\nresponse = requests.post(url, json=payload, headers=headers)\n\nprint(response.json())","Upload the image or video",{"body":129,"note":130,"operationId":131,"operation_url":68,"snippet":132,"title":134,"webhook":120},"Attach the uploaded media with a caption. This is the format shops use for a daily menu or new stock, because the picture does the work and the caption carries the price or the time.","In Python post the media status with the media id and the caption in the json= dict, catching requests.HTTPError so a 413 payload_too_large or a 415 unsupported_media_type is reported with the file name rather than as a traceback. The caption is where the price or the time goes.","postMediaStory",{"code":133,"lang":39},"import requests\n\nurl = \"https:\u002F\u002Fapi.wapito.com\u002Fv1\u002Fstories\u002Fmedia\"\n\npayload = {\n    \"media\": \"https:\u002F\u002Facme.example\u002Fstatus\u002Fnew-colours.jpg\",\n    \"caption\": \"New colours, same price.\",\n    \"contacts\": [\"+15551234567\"]\n}\nheaders = {\n    \"Authorization\": \"Bearer wpt_YOUR_TOKEN\",\n    \"Content-Type\": \"application\u002Fjson\"\n}\n\nresponse = requests.post(url, json=payload, headers=headers)\n\nprint(response.json())","Post the media status",{"body":136,"note":137,"operationId":138,"operation_url":71,"snippet":139,"title":141,"webhook":120},"A short voice note as a status is unusual enough to get attention and personal enough to be worth it occasionally. The audio must be Opus-encoded, the same as a voice message.","In Python a voice status needs Opus audio; convert with a subprocess call to ffmpeg before uploading, since Python has no built-in encoder for it, then post the media id to \u002Fstories\u002Faudio. Check the returned status code; the endpoint rejects an MP3 with unsupported_media_type.","postAudioStory",{"code":140,"lang":39},"import requests\n\nurl = \"https:\u002F\u002Fapi.wapito.com\u002Fv1\u002Fstories\u002Faudio\"\n\npayload = {\n    \"media\": \"https:\u002F\u002Facme.example\u002Fstatus\u002Fmonday-update.m4a\",\n    \"background_color\": \"#1D2B3A\"\n}\nheaders = {\n    \"Authorization\": \"Bearer wpt_YOUR_TOKEN\",\n    \"Content-Type\": \"application\u002Fjson\"\n}\n\nresponse = requests.post(url, json=payload, headers=headers)\n\nprint(response.json())","Post a voice status","t2",{"code":144,"events":145,"filename":148,"framework":149,"install":150,"lang":39},"import hashlib\nimport hmac\nimport os\nimport time\n\nfrom fastapi import FastAPI, Header, HTTPException, Request\n\napp = FastAPI()\nSECRET = os.environ[\"WAPITO_WEBHOOK_SECRET\"].encode()\nEVENTS = [\"messages\", \"messages.status\"]\n\n\ndef verify(raw: bytes, header: str | None) -> bool:\n    \"\"\"Checks the X-Wapito-Signature header: t=\u003Cms>,v1=\u003Chex hmac-sha256>.\"\"\"\n    if not header:\n        return False\n    parts = dict(p.split(\"=\", 1) for p in header.split(\",\") if \"=\" in p)\n    ts, sig = parts.get(\"t\"), parts.get(\"v1\")\n    if not ts or not sig:\n        return False\n    if abs(time.time() * 1000 - int(ts)) > 300_000:  # 5 minute clock skew\n        return False\n    expected = hmac.new(SECRET, ts.encode() + b\".\" + raw, hashlib.sha256).hexdigest()\n    return hmac.compare_digest(expected, sig)\n\n\n@app.post(\"\u002Fwapito\")\nasync def wapito(request: Request, signature: str | None = Header(default=None, alias=\"X-Wapito-Signature\")):\n    raw = await request.body()\n    if not verify(raw, signature):\n        raise HTTPException(status_code=401, detail=\"bad signature\")\n    payload = await request.json()\n    if payload[\"event\"] in EVENTS:\n        print(payload[\"event\"], payload[\"data\"])\n    return {\"ok\": True}  # answer 2xx fast; do the real work in a queue\n",[146,147],"messages","messages.status","webhook.py","FastAPI","pip install fastapi uvicorn",[152,154,156,158,160,162],{"label":49,"id":39,"lang":39,"code":118,"html":153},"\u003Cpre class=\"shiki shiki-themes github-light-default github-dark-default\" style=\"background-color:#ffffff;--shiki-dark-bg:#0d1117;color:#1f2328;--shiki-dark:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">import\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> requests\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">url \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"https:\u002F\u002Fapi.wapito.com\u002Fv1\u002Fstories\u002Ftext\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">payload \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"body\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Workshop closed Friday for stocktake. Orders ship Monday.\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"background_color\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"#0B7F5C\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"font\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">2\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"contacts\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: [\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"+15551234567\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"+15559876543\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">]\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">headers \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"Authorization\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Bearer wpt_YOUR_TOKEN\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"Content-Type\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"application\u002Fjson\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">response \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> requests.post(url, \u003C\u002Fspan>\u003Cspan style=\"color:#953800;--shiki-dark:#FFA657\">json\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">payload, \u003C\u002Fspan>\u003Cspan style=\"color:#953800;--shiki-dark:#FFA657\">headers\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">headers)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">print\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(response.json())\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",{"label":49,"id":39,"lang":39,"code":126,"html":155},"\u003Cpre class=\"shiki shiki-themes github-light-default github-dark-default\" style=\"background-color:#ffffff;--shiki-dark-bg:#0d1117;color:#1f2328;--shiki-dark:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">import\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> requests\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">url \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"https:\u002F\u002Fapi.wapito.com\u002Fv1\u002Fmedia\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">payload \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"data\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"data:image\u002Fjpeg;base64,\u002F9j\u002F4AAQSkZJRgABAQEASABIAAD\u002F2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD…\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"filename\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"new-colours.jpg\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">headers \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"Authorization\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Bearer wpt_YOUR_TOKEN\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"Content-Type\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"application\u002Fjson\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">response \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> requests.post(url, \u003C\u002Fspan>\u003Cspan style=\"color:#953800;--shiki-dark:#FFA657\">json\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">payload, \u003C\u002Fspan>\u003Cspan style=\"color:#953800;--shiki-dark:#FFA657\">headers\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">headers)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">print\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(response.json())\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",{"label":49,"id":39,"lang":39,"code":133,"html":157},"\u003Cpre class=\"shiki shiki-themes github-light-default github-dark-default\" style=\"background-color:#ffffff;--shiki-dark-bg:#0d1117;color:#1f2328;--shiki-dark:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">import\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> requests\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">url \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"https:\u002F\u002Fapi.wapito.com\u002Fv1\u002Fstories\u002Fmedia\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">payload \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"media\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"https:\u002F\u002Facme.example\u002Fstatus\u002Fnew-colours.jpg\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"caption\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"New colours, same price.\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"contacts\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: [\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"+15551234567\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">]\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">headers \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"Authorization\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Bearer wpt_YOUR_TOKEN\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"Content-Type\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"application\u002Fjson\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">response \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> requests.post(url, \u003C\u002Fspan>\u003Cspan style=\"color:#953800;--shiki-dark:#FFA657\">json\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">payload, \u003C\u002Fspan>\u003Cspan style=\"color:#953800;--shiki-dark:#FFA657\">headers\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">headers)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">print\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(response.json())\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",{"label":49,"id":39,"lang":39,"code":140,"html":159},"\u003Cpre class=\"shiki shiki-themes github-light-default github-dark-default\" style=\"background-color:#ffffff;--shiki-dark-bg:#0d1117;color:#1f2328;--shiki-dark:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">import\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> requests\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">url \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"https:\u002F\u002Fapi.wapito.com\u002Fv1\u002Fstories\u002Faudio\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">payload \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"media\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"https:\u002F\u002Facme.example\u002Fstatus\u002Fmonday-update.m4a\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"background_color\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"#1D2B3A\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">headers \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"Authorization\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Bearer wpt_YOUR_TOKEN\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"Content-Type\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"application\u002Fjson\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">response \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> requests.post(url, \u003C\u002Fspan>\u003Cspan style=\"color:#953800;--shiki-dark:#FFA657\">json\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">payload, \u003C\u002Fspan>\u003Cspan style=\"color:#953800;--shiki-dark:#FFA657\">headers\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">headers)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">print\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(response.json())\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",{"label":49,"id":39,"lang":39,"code":37,"html":161},"\u003Cpre class=\"shiki shiki-themes github-light-default github-dark-default\" style=\"background-color:#ffffff;--shiki-dark-bg:#0d1117;color:#1f2328;--shiki-dark:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"\"\"Post Status with the Wapito WhatsApp API.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">Post a text card, or upload media once and post it as an image, video or voice status with a caption that carries the detail.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">Run it with:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    export WAPITO_TOKEN=\"wpt_...\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    python post-status.py\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"\"\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">import\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> os\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">import\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> requests\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">BASE_URL\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"https:\u002F\u002Fapi.wapito.com\u002Fv1\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">TOKEN\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> os.environ[\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"WAPITO_TOKEN\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">]\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6E7781;--shiki-dark:#8B949E\"># --- Post a text card ---\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">url \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> BASE_URL\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> +\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"\u002Fstories\u002Ftext\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">payload \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"body\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Workshop closed Friday for stocktake. Orders ship Monday.\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"background_color\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"#0B7F5C\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"font\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">2\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"contacts\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: [\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"+15551234567\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"+15559876543\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">]\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">headers \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"Authorization\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Bearer \"\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> +\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> TOKEN\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"Content-Type\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"application\u002Fjson\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">response \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> requests.post(url, \u003C\u002Fspan>\u003Cspan style=\"color:#953800;--shiki-dark:#FFA657\">json\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">payload, \u003C\u002Fspan>\u003Cspan style=\"color:#953800;--shiki-dark:#FFA657\">headers\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">headers)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">print\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(response.json())\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6E7781;--shiki-dark:#8B949E\"># --- Upload the image or video ---\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">url \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> BASE_URL\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> +\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"\u002Fmedia\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">payload \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"data\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"data:image\u002Fjpeg;base64,\u002F9j\u002F4AAQSkZJRgABAQEASABIAAD\u002F2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD…\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"filename\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"new-colours.jpg\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">headers \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"Authorization\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Bearer \"\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> +\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> TOKEN\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"Content-Type\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"application\u002Fjson\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">response \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> requests.post(url, \u003C\u002Fspan>\u003Cspan style=\"color:#953800;--shiki-dark:#FFA657\">json\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">payload, \u003C\u002Fspan>\u003Cspan style=\"color:#953800;--shiki-dark:#FFA657\">headers\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">headers)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">print\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(response.json())\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6E7781;--shiki-dark:#8B949E\"># --- Post the media status ---\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">url \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> BASE_URL\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> +\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"\u002Fstories\u002Fmedia\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">payload \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"media\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"https:\u002F\u002Facme.example\u002Fstatus\u002Fnew-colours.jpg\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"caption\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"New colours, same price.\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"contacts\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: [\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"+15551234567\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">]\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">headers \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"Authorization\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Bearer \"\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> +\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> TOKEN\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"Content-Type\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"application\u002Fjson\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">response \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> requests.post(url, \u003C\u002Fspan>\u003Cspan style=\"color:#953800;--shiki-dark:#FFA657\">json\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">payload, \u003C\u002Fspan>\u003Cspan style=\"color:#953800;--shiki-dark:#FFA657\">headers\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">headers)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">print\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(response.json())\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#6E7781;--shiki-dark:#8B949E\"># --- Post a voice status ---\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">url \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> BASE_URL\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> +\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"\u002Fstories\u002Faudio\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">payload \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"media\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"https:\u002F\u002Facme.example\u002Fstatus\u002Fmonday-update.m4a\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"background_color\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"#1D2B3A\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">headers \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"Authorization\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Bearer \"\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> +\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> TOKEN\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"Content-Type\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"application\u002Fjson\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">response \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> requests.post(url, \u003C\u002Fspan>\u003Cspan style=\"color:#953800;--shiki-dark:#FFA657\">json\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">payload, \u003C\u002Fspan>\u003Cspan style=\"color:#953800;--shiki-dark:#FFA657\">headers\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">headers)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">print\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(response.json())\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",{"label":149,"id":39,"lang":39,"code":144,"html":163},"\u003Cpre class=\"shiki shiki-themes github-light-default github-dark-default\" style=\"background-color:#ffffff;--shiki-dark-bg:#0d1117;color:#1f2328;--shiki-dark:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">import\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> hashlib\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">import\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> hmac\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">import\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> os\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">import\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> time\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">from\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> fastapi \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">import\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> FastAPI, Header, HTTPException, Request\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">app \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> FastAPI()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">SECRET\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> os.environ[\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"WAPITO_WEBHOOK_SECRET\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">].encode()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">EVENTS\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> [\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"messages\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"messages.status\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">]\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">def\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> verify\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(raw: \u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">bytes\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, header: \u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">str\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> |\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> None\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) -> \u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">bool\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">    \"\"\"Checks the X-Wapito-Signature header: t=&#x3C;ms>,v1=&#x3C;hex hmac-sha256>.\"\"\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">    if\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> not\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> header:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">        return\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> False\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    parts \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> dict\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(p.split(\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"=\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">1\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">for\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> p \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">in\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> header.split(\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\",\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">if\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> \"=\"\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> in\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> p)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    ts, sig \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> parts.get(\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"t\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">), parts.get(\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"v1\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">    if\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> not\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> ts \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">or\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> not\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> sig:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">        return\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> False\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">    if\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> abs\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(time.time() \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">*\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 1000\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> -\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> int\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(ts)) \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">>\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> 300_000\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">:  \u003C\u002Fspan>\u003Cspan style=\"color:#6E7781;--shiki-dark:#8B949E\"># 5 minute clock skew\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">        return\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> False\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    expected \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> hmac.new(\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">SECRET\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, ts.encode() \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">+\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> b\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\".\"\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> +\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> raw, hashlib.sha256).hexdigest()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">    return\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> hmac.compare_digest(expected, sig)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\">@app.post\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"\u002Fwapito\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">async\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> def\u003C\u002Fspan>\u003Cspan style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> wapito\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(request: Request, signature: \u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">str\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> |\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> None\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> Header(\u003C\u002Fspan>\u003Cspan style=\"color:#953800;--shiki-dark:#FFA657\">default\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">None\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#953800;--shiki-dark:#FFA657\">alias\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"X-Wapito-Signature\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)):\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    raw \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> await\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> request.body()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">    if\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> not\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> verify(raw, signature):\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">        raise\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> HTTPException(\u003C\u002Fspan>\u003Cspan style=\"color:#953800;--shiki-dark:#FFA657\">status_code\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">401\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, \u003C\u002Fspan>\u003Cspan style=\"color:#953800;--shiki-dark:#FFA657\">detail\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"bad signature\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    payload \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\"> await\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> request.json()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">    if\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> payload[\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"event\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">] \u003C\u002Fspan>\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">in\u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\"> EVENTS\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">        print\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(payload[\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"event\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">], payload[\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"data\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">])\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#CF222E;--shiki-dark:#FF7B72\">    return\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {\u003C\u002Fspan>\u003Cspan style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"ok\"\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: \u003C\u002Fspan>\u003Cspan style=\"color:#0550AE;--shiki-dark:#79C0FF\">True\u003C\u002Fspan>\u003Cspan style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}  \u003C\u002Fspan>\u003Cspan style=\"color:#6E7781;--shiki-dark:#8B949E\"># answer 2xx fast; do the real work in a queue\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",1790464902715]