Bot API

Build bots, automate messaging, and integrate OSHI into your applications

Quick Navigation

Overview

The OSHI Bot API lets you create bots that can send messages to groups and channels, similar to Telegram's Bot API. Bots are created from the OSHI app and controlled programmatically via HTTP endpoints.

🤖

Create Bots

Create bots directly from the OSHI app with a Telegram BotFather-like wizard

🔑

Token Auth

Each bot gets a unique token for secure API access

📡

HTTP API

Simple REST API - send messages from any language with a single POST request

🐍

Python SDK

Official Python SDK with OshiBot class for quick integration

Triggers

Keyword, command, schedule, and webhook triggers built-in

🔗

MoltBot

Bridge class for MoltBot framework integration

Getting Started

Follow these 4 steps to create a bot and start sending messages:

1

Create a Bot

Open OSHI app > Portal > Bots > tap "+" to create a new bot

2

Copy Token

After creation, copy the bot token shown on the success screen

3

Assign to Group

Add the bot to a group from Bot Settings > Assigned Groups

4

Send Messages

Use the API, Python SDK, or curl to send messages via your token

Base URL

https://oshi-messenger.com

Keep Your Token Secret

Your bot token grants full access to send messages. Never share it publicly or commit it to version control.

API Endpoints

POST /api/bot/send

Send a message to a group via bot token. This is the primary endpoint for bot messaging.

Request Body

ParameterTypeRequiredDescription
tokenstringYesBot token from OSHI app
groupIdstringYesUUID of the target group. Find it in OSHI App → Group → Info → Group ID (tap to copy)
contentstringConditionalMessage text or caption. Required unless mediaData is provided.
mediaTypestringNoMedia type: photo, video, audio, or document
mediaDatastringNoBase64-encoded file data (max 10 MB raw size)
mediaFileNamestringNoOriginal filename (e.g., report.pdf). Required when mediaData is provided.
Where to find your credentials
Bot Token — Shown after bot creation, or in Bot Settings → API section. Tap to copy.
Group ID — Open the group in OSHI → tap group name → Group InfoGroup ID. Tap "Copy ID".

Request

curlcurl -X POST https://oshi-messenger.com/api/bot/send \
  -H "Content-Type: application/json" \
  -d '{
    "token": "YOUR_BOT_TOKEN",
    "groupId": "GROUP_UUID",
    "content": "Hello from my bot"
  }'

Response

{ "success": true, "delivered": 3, "totalMembers": 3, "messageId": "67a37679-9cc7-4d78-bdf9-ffadcb6fa0ef", "groupName": "My Channel", "hasMedia": false }
POST /api/bot/register

Register a bot with the server. Automatically called by the OSHI app, but can also be called manually for programmatic registration.

Request Body

ParameterTypeRequiredDescription
tokenstringYesBot token
botNamestringYesDisplay name for the bot
ownerPublicKeystringYesCreator's public key
groupsarrayNoGroups to assign: [{id, name, members}]
curlcurl -X POST https://oshi-messenger.com/api/bot/register \
  -H "Content-Type: application/json" \
  -d '{
    "token": "YOUR_BOT_TOKEN",
    "botName": "My Alert Bot",
    "ownerPublicKey": "your_public_key",
    "groups": [{
      "id": "group-uuid",
      "name": "Alerts",
      "members": ["member1_key", "member2_key"]
    }]
  }'
GET /api/bot/info?token=YOUR_TOKEN

Get bot info, stats, and assigned groups.

curlcurl "https://oshi-messenger.com/api/bot/info?token=YOUR_BOT_TOKEN"

Response

{ "success": true, "bot": { "botName": "My Alert Bot", "registeredAt": "2026-02-20T03:52:44.684Z", "groups": [ { "id": "uuid", "name": "Alerts", "memberCount": 5 } ], "stats": { "messagesSent": 42, "lastActivity": "2026-02-20T12:00:00Z" } } }
POST /api/bot/update-groups

Update the bot's group assignments.

ParameterTypeRequiredDescription
tokenstringYesBot token
groupsarrayYesNew groups: [{id, name, members}]
GET /api/bot/list

List all registered bots with stats.

curlcurl https://oshi-messenger.com/api/bot/list
DELETE /api/bot/unregister?token=YOUR_TOKEN

Remove a bot from the server registry.

curlcurl -X DELETE "https://oshi-messenger.com/api/bot/unregister?token=YOUR_BOT_TOKEN"

Python SDK

The official Python SDK provides a clean OshiBot class for easy integration. Only requires the requests library.

Installation

bashpip install requests
# Download the SDK
curl -O https://oshi-messenger.com/sdk/oshi_bot.py

Quick Start

pythonfrom oshi_bot import OshiBot

# Initialize with your bot token
bot = OshiBot(token="YOUR_BOT_TOKEN")

# Send a message to a group
result = bot.send("GROUP_UUID", "Hello from Python!")
print(f"Delivered to {result['delivered']} members")

# Get bot info
info = bot.info()
print(f"Bot: {info['bot']['botName']}")
print(f"Messages sent: {info['bot']['stats']['messagesSent']}")

# Send to all assigned groups
results = bot.send_to_all_groups("Broadcast message!")

# Get groups list
groups = bot.get_groups()
for g in groups:
    print(f"  {g['name']} ({g['memberCount']} members)")

Sending Media

python# Send an image with caption
bot.send_image("GROUP_UUID", "/path/to/chart.png", caption="Daily chart")

# Send a document
bot.send_document("GROUP_UUID", "/path/to/report.pdf", caption="Q4 Report")

# Send any file (auto-detects type from extension)
bot.send_file("GROUP_UUID", "/path/to/data.csv")

# Low-level: send raw base64 media
import base64
with open("photo.jpg", "rb") as f:
    data = base64.b64encode(f.read()).decode()
bot.send_media("GROUP_UUID", "photo", data, "photo.jpg", content="Check this!")

Command Line

bash# Send a message
python oshi_bot.py send YOUR_TOKEN GROUP_ID "Hello!"

# Get bot info
python oshi_bot.py info YOUR_TOKEN

# List groups
python oshi_bot.py groups YOUR_TOKEN

# Check stats
python oshi_bot.py stats YOUR_TOKEN

# List all bots on server
python oshi_bot.py list

Code Examples

Send a Message

pythonimport requests

response = requests.post("https://oshi-messenger.com/api/bot/send", json={
    "token": "YOUR_BOT_TOKEN",
    "groupId": "550e8400-e29b-41d4-a716-446655440000",
    "content": "Market update: BTC +2.5% today"
})

data = response.json()
if data["success"]:
    print(f"Delivered to {data['delivered']} members")
else:
    print(f"Error: {data.get('error')}")

Alert Bot Example

pythonfrom oshi_bot import OshiBot
import schedule, time

bot = OshiBot(token="YOUR_BOT_TOKEN")
GROUP = "your-group-uuid"

def send_daily_report():
    report = generate_report()  # your logic
    bot.send(GROUP, f"Daily Report\n{report}")

schedule.every().day.at("09:00").do(send_daily_report)

while True:
    schedule.run_pending()
    time.sleep(60)

Send Media (Photo / Document)

pythonimport base64, requests

# --- Send a photo ---
with open("chart.png", "rb") as f:
    img_b64 = base64.b64encode(f.read()).decode()

requests.post("https://oshi-messenger.com/api/bot/send", json={
    "token": "YOUR_BOT_TOKEN",
    "groupId": "GROUP_UUID",
    "content": "Daily chart",
    "mediaType": "photo",
    "mediaData": img_b64,
    "mediaFileName": "chart.png"
})

# --- Send a document ---
with open("report.pdf", "rb") as f:
    doc_b64 = base64.b64encode(f.read()).decode()

requests.post("https://oshi-messenger.com/api/bot/send", json={
    "token": "YOUR_BOT_TOKEN",
    "groupId": "GROUP_UUID",
    "content": "Monthly report",
    "mediaType": "document",
    "mediaData": doc_b64,
    "mediaFileName": "report.pdf"
})

Send a Message

bashcurl -X POST https://oshi-messenger.com/api/bot/send \
  -H "Content-Type: application/json" \
  -d '{
    "token": "YOUR_BOT_TOKEN",
    "groupId": "GROUP_UUID",
    "content": "Hello from curl"
  }'

Register a Bot

bashcurl -X POST https://oshi-messenger.com/api/bot/register \
  -H "Content-Type: application/json" \
  -d '{
    "token": "YOUR_BOT_TOKEN",
    "botName": "My Bot",
    "ownerPublicKey": "your_public_key",
    "groups": []
  }'

Check Bot Info

bashcurl "https://oshi-messenger.com/api/bot/info?token=YOUR_BOT_TOKEN"

Send a File

bash# Encode file and send as media
FILE_B64=$(base64 -i chart.png)

curl -X POST https://oshi-messenger.com/api/bot/send \
  -H "Content-Type: application/json" \
  -d "{
    \"token\": \"YOUR_BOT_TOKEN\",
    \"groupId\": \"GROUP_UUID\",
    \"content\": \"Daily chart\",
    \"mediaType\": \"photo\",
    \"mediaData\": \"$FILE_B64\",
    \"mediaFileName\": \"chart.png\"
  }"

Node.js / JavaScript

javascript// Send a message with fetch
const response = await fetch("https://oshi-messenger.com/api/bot/send", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    token: "YOUR_BOT_TOKEN",
    groupId: "GROUP_UUID",
    content: "Hello from JavaScript!"
  })
});

const data = await response.json();
console.log(`Delivered to ${data.delivered} members`);

Node.js with axios

javascriptconst axios = require("axios");

const { data } = await axios.post("https://oshi-messenger.com/api/bot/send", {
  token: "YOUR_BOT_TOKEN",
  groupId: "GROUP_UUID",
  content: "Hello from Node.js!"
});

console.log(data);

Send a File (Node.js)

javascriptconst fs = require("fs");

const fileData = fs.readFileSync("report.pdf").toString("base64");

const response = await fetch("https://oshi-messenger.com/api/bot/send", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    token: "YOUR_BOT_TOKEN",
    groupId: "GROUP_UUID",
    content: "Monthly report",
    mediaType: "document",
    mediaData: fileData,
    mediaFileName: "report.pdf"
  })
});

Go

gopackage main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "net/http"
)

func main() {
    payload, _ := json.Marshal(map[string]string{
        "token":   "YOUR_BOT_TOKEN",
        "groupId": "GROUP_UUID",
        "content": "Hello from Go!",
    })

    resp, err := http.Post(
        "https://oshi-messenger.com/api/bot/send",
        "application/json",
        bytes.NewBuffer(payload),
    )
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    var result map[string]interface{}
    json.NewDecoder(resp.Body).Decode(&result)
    fmt.Printf("Delivered: %v\n", result["delivered"])
}

Send a File

gofileBytes, _ := os.ReadFile("report.pdf")
fileB64 := base64.StdEncoding.EncodeToString(fileBytes)

payload, _ := json.Marshal(map[string]string{
    "token":         "YOUR_BOT_TOKEN",
    "groupId":       "GROUP_UUID",
    "content":       "Monthly report",
    "mediaType":     "document",
    "mediaData":     fileB64,
    "mediaFileName": "report.pdf",
})

resp, _ := http.Post(
    "https://oshi-messenger.com/api/bot/send",
    "application/json",
    bytes.NewBuffer(payload),
)

Media & Files

Bots can send images, videos, audio, and documents alongside text messages. Media is sent as Base64-encoded data within the JSON payload.

Supported Media Types

TypeValueExtensionsMax Size
photo"photo"PNG, JPG, GIF, WebP, HEIC10 MB
video"video"MP4, MOV, AVI10 MB
audio"audio"MP3, M4A, WAV, OGG10 MB
document"document"PDF, TXT, DOCX, CSV, any10 MB

Size Limit

Media data is limited to 10 MB (raw file size, before Base64 encoding). The total request body limit is 15 MB to accommodate Base64 overhead (~33%).

How It Works

  1. Read the file and encode it as Base64
  2. Include mediaType, mediaData, and mediaFileName in the request body
  3. The content field serves as an optional caption
  4. OSHI clients render the media inline with the caption

Encryption & Security

All messages in OSHI benefit from the same encryption pipeline used for user messages. Bot messages are encrypted before being stored on IPFS.

How Bot Messages Are Secured

  1. TLS in transit — Bot sends message via HTTPS to /api/bot/send
  2. Server queues — Message is queued for each group member
  3. AES-256-GCM encryption — OSHI client encrypts the message with a derived group key
  4. IPFS storage — Encrypted payload is pinned to IPFS via Pinata for decentralized delivery
  5. Client decryption — Only group members can derive the key and decrypt

Encrypted Envelope (v2)

Messages stored on IPFS are wrapped in an encrypted envelope. Only the version number and a short routing hint are visible:

{ "v": 2, "envelope": "aGVsbG8gd29ybGQ...", "hint": "a1b2", "nonce": "dW5pcXVlbm9uY2U..." }

Hidden inside the encrypted envelope:

  • Message content, sender key, recipient keys
  • Timestamp, group ID, message chain index
  • Media type and attachment data

Encryption Details

  • Algorithm: AES-256-GCM (authenticated encryption with associated data)
  • Key derivation: SHA-256 HKDF from shared group secret + salt
  • Nonce: Unique random nonce per message (prevents replay attacks)
  • Integrity: GCM authentication tag prevents tampering
  • Storage: IPFS (decentralized, content-addressed, immutable)

MoltBot Integration

The OSHI SDK includes an OshiMoltBotBridge class that acts as a transport/output plugin for the MoltBot multi-platform bot framework.

pythonfrom oshi_bot import OshiMoltBotBridge

# Initialize bridge
bridge = OshiMoltBotBridge(
    oshi_token="YOUR_BOT_TOKEN",
    default_group="GROUP_UUID"
)

# Send to default group
bridge.send("Hello from MoltBot!")

# Send to specific group
bridge.send("Alert!", group_id="other-group-uuid")

# Broadcast to all groups
bridge.broadcast("System maintenance in 5 minutes")

# Use as MoltBot output plugin
class MyMoltBot:
    def __init__(self):
        self.outputs = [bridge]

    def on_event(self, event):
        message = f"Event: {event['type']} - {event['data']}"
        for output in self.outputs:
            output.send(message)

Bot Types

OSHI supports 4 bot types, each designed for different use cases:

⚙️

Automation

Responds to keyword/command triggers in group messages

🌐

Webhook

Receives events via HTTP POST from external services

Scheduled

Sends messages on a timer (daily reports, reminders)

🛡️

Moderator

Welcome messages, rules enforcement, group management

Rate Limits

LimitValueDescription
Messages/minute60Per bot token, sliding window
Request body15 MBMax JSON payload size (includes Base64-encoded media)
Media file10 MBMax raw file size per media attachment
Content lengthNo limitMessage content has no character limit

Auto-Retry

The Python SDK automatically retries once after a 5-second wait when rate limited. Set auto_retry=False to disable.

Error Handling

HTTP CodeErrorCause
400Bad RequestMissing required fields (token, groupId) or missing both content and mediaData
401UnauthorizedInvalid bot token. Register the bot first.
403ForbiddenBot not assigned to this group
404Not FoundBot not found (for info/unregister)
429Too Many RequestsRate limit exceeded (60/min)

Python Error Handling

pythonfrom oshi_bot import OshiBot, OshiAuthError, OshiGroupError, OshiRateLimitError

bot = OshiBot(token="YOUR_TOKEN")

try:
    bot.send("GROUP_ID", "Hello!")
except OshiAuthError:
    print("Invalid token - register the bot first")
except OshiGroupError:
    print("Bot not assigned to this group")
except OshiRateLimitError:
    print("Slow down - rate limit exceeded")