Skip to main content
A complete example of sending a text message over the Asgard REST API and reading the response

Sending a message

This example sends a message to a bot provider over the Asgard REST API and reads the response.

The endpoint​

POST {{base_url}}/generic/ns/{{namespace}}/bot-provider/{{bot_provider_name}}/message/sse

About customChannelId​

customChannelId identifies a conversation, and it is what keeps the memory of a session together. Send several messages with the same customChannelId and the bot remembers what came before. To start a new conversation, use a different one.


cURL​

curl -X POST "https://api.asgard-ai.com/generic/ns/your-namespace/bot-provider/your-bot-provider/message/sse" \
-H "Content-Type: application/json" \
-H "X-API-KEY: your-api-key" \
-d '{
"customChannelId": "channel-001",
"customMessageId": "msg-001",
"text": "How do I reset my password?",
"action": "NONE"
}'

JavaScript (fetch)​

const BASE_URL = 'https://api.asgard-ai.com';
const NAMESPACE = 'your-namespace';
const BOT_PROVIDER = 'your-bot-provider';
const API_KEY = process.env.ASGARD_API_KEY;

async function sendMessage(channelId, messageId, text) {
const url = `${BASE_URL}/generic/ns/${NAMESPACE}/bot-provider/${BOT_PROVIDER}/message/sse`;

const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-KEY': API_KEY,
},
body: JSON.stringify({
customChannelId: channelId,
customMessageId: messageId,
text: text,
action: 'NONE',
}),
});

if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}

// read the SSE stream and accumulate the full response
const reader = response.body.getReader();
const decoder = new TextDecoder();
let fullText = '';

while (true) {
const { done, value } = await reader.read();
if (done) break;

const chunk = decoder.decode(value, { stream: true });
const lines = chunk.split('\n');

for (const line of lines) {
if (!line.startsWith('data:')) continue;

const jsonStr = line.slice(5).trim();
if (!jsonStr) continue;

try {
const event = JSON.parse(jsonStr);

if (event.eventType === 'asgard.message.delta') {
fullText += event.fact.messageDelta.message.text;
}

if (event.eventType === 'asgard.message.complete') {
console.log('Full response:', fullText);
}

if (event.eventType === 'asgard.run.done') {
console.log('Request complete');
return fullText;
}
} catch (e) {
// ignore a line that will not parse
}
}
}

return fullText;
}

// usage
sendMessage('channel-001', 'msg-001', 'How do I reset my password?')
.then((reply) => console.log('Bot reply:', reply))
.catch(console.error);

Python (requests)​

import requests
import json
import os

BASE_URL = "https://api.asgard-ai.com"
NAMESPACE = "your-namespace"
BOT_PROVIDER = "your-bot-provider"
API_KEY = os.environ.get("ASGARD_API_KEY")

def send_message(channel_id: str, message_id: str, text: str) -> str:
url = f"{BASE_URL}/generic/ns/{NAMESPACE}/bot-provider/{BOT_PROVIDER}/message/sse"

headers = {
"Content-Type": "application/json",
"X-API-KEY": API_KEY,
}

payload = {
"customChannelId": channel_id,
"customMessageId": message_id,
"text": text,
"action": "NONE",
}

full_text = ""

with requests.post(url, headers=headers, json=payload, stream=True) as response:
response.raise_for_status()

for line in response.iter_lines():
if not line:
continue

decoded = line.decode("utf-8")
if not decoded.startswith("data:"):
continue

json_str = decoded[5:].strip()
if not json_str:
continue

try:
event = json.loads(json_str)
event_type = event.get("eventType")

if event_type == "asgard.message.delta":
text_chunk = event["fact"]["messageDelta"]["message"]["text"]
full_text += text_chunk

elif event_type == "asgard.message.complete":
print(f"Full response: {full_text}")

elif event_type == "asgard.run.done":
print("Request complete")
break

except json.JSONDecodeError:
pass

return full_text


if __name__ == "__main__":
reply = send_message("channel-001", "msg-001", "How do I reset my password?")
print(f"Bot reply: {reply}")

The response events​

After you send a message, the API returns a series of events as an SSE (Server-Sent Events) stream:

Event typeWhat it is
asgard.run.initThe request initialises, carrying the runId and other details
asgard.message.deltaA piece of the message, which is what produces the typewriter effect
asgard.message.completeThe complete message, with the template render data
asgard.run.doneThe request ends and the stream closes

For the detailed event format see the SSE response events.

Next​