REFERENCE
Developer Reference
Authentication, APIs, SDKs, Flow Agent processors and parameter resolution, in full.
Sending a message
A complete example of sending a text message over the Asgard REST API and reading the response
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/sseAbout customChannelId
customChannelIdidentifies a conversation, and it is what keeps the memory of a session together. Send several messages with the samecustomChannelIdand 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 type What 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
- Handling a streamed response — building the typewriter effect and a live streaming interface
- Querying a knowledge base — question and answer against a RAG knowledge base