Custom keyboard not appearing in Telegram bot using Python

I’m working on a Telegram bot using Python and having trouble getting custom keyboards to show up. When I try to send a message with a reply keyboard, nothing appears on the user side.

Here’s my current implementation:

bot_api.post(BOT_URL + "sendMessage", 
    data={
        'chat_id': USER_ID, 
        'text': "Choose an option:", 
        'reply_markup': {
            'keyboard': menu_options, 
            'one_time_keyboard': True, 
            'resize_keyboard': True
        }
    }
)

My menu structure looks like this:

menu_options = [["Option 1"], ["Option 2"], ["Option 3"]]

The message sends successfully but the keyboard doesn’t display. Has anyone encountered this issue before? What could be causing the keyboard to not appear?

You’re not encoding the reply_markup as JSON properly. Telegram expects reply_markup to be a JSON string, not a Python dictionary when you’re using requests or similar HTTP clients.

Here’s the fix: import json at the top, then change your data dictionary to include ‘reply_markup’: json.dumps({‘keyboard’: menu_options, ‘one_time_keyboard’: True, ‘resize_keyboard’: True}).

I had this exact same problem when I started with Telegram bots - this simple change fixed it right away. The bot API is pretty strict about how it wants structured data like keyboards formatted.

yeah, this trips up a lot of ppl! double-check your http headers - you need content-type set to application/x-www-form-urlencoded for form data. also make sure USER_ID is valid and that the user messaged your bot first. telegram won’t display keyboards to users who haven’t started a convo with your bot.

Check if you’re using the right HTTP method and request structure. I had the same problem when I mixed up the data vs json parameters in requests. If you’re using the requests library, switch to the json parameter and drop the json.dumps() call - just do requests.post(url, json={‘chat_id’: USER_ID, ‘text’: ‘Choose an option:’, ‘reply_markup’: {‘keyboard’: menu_options, ‘one_time_keyboard’: True, ‘resize_keyboard’: True}}). This handles JSON serialization automatically and sets the right headers. Also double-check your bot token and permissions - keyboards sometimes break when there are API issues.