API
Your own software can message a sleeve and read its answer over HTTPS, with an organization API key. This is the same Converse the console uses.
API keys
Owners create keys on Org → API keys in the console. A key:
- is shown once, when you create it: copy it then (it starts with
sc_); - can message only the stacks you choose when you create it, or every stack;
- cannot read memory, traces, specs or members, and cannot change anything;
- can be revoked at any time, effective on the next call.
Sleevecast stores only a hash of each key. API keys are part of the Pro and Team plans.
Send a message
POST https://api.sleevecast.com/v1/sleeves/{stack}/messages
Authorization: Bearer sc_…
Content-Type: application/json
{ "message": "Summarize today's support tickets in three bullets." }
The answer is 202 Accepted with a message id:
{ "id": "dk1a2b3c4d5e6f70_9f86d081884c7d659a2feaa0c55ad015" }
If the stack runs on more than one Dock, name one with "dock": "<dock id>".
Read the answer
GET https://api.sleevecast.com/v1/messages/{id}
Authorization: Bearer sc_…
The call waits up to 25 seconds for the answer. Call it again until done is true:
{ "id": "dk1a…_9f86…", "done": true, "text": "• 14 tickets…", "error": null }
When the sleeve could not answer (for example, a guard tripped), done is true and error says why. An answer is returned once and kept for 45 minutes.
Errors
| Status | Meaning |
|---|---|
| 400 | The message is empty or longer than 16,000 characters. |
| 401 | No key, an unknown key or a revoked key. |
| 403 | The key may not message that stack. |
| 404 | The stack is not running on any Dock, or the message id is unknown or already read. |
| 409 | The stack runs on several Docks and no dock was given, or the Dock refused the message. |
| 429 | More than 60 calls a minute with one key; wait for Retry-After seconds. |
| 503 | The Dock is offline or did not answer. |
Every error has a JSON body { "error": "…" } that explains it.
Examples
curl
KEY=sc_...
ID=$(curl -s -X POST https://api.sleevecast.com/v1/sleeves/scout/messages \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"message":"What changed in our market this week?"}' | jq -r .id)
until R=$(curl -s https://api.sleevecast.com/v1/messages/$ID -H "Authorization: Bearer $KEY") && [ "$(echo "$R" | jq .done)" = true ]; do :; done
echo "$R" | jq -r '.text // .error'
Python
import requests
API = "https://api.sleevecast.com/v1"
headers = {"Authorization": "Bearer sc_..."}
msg = requests.post(f"{API}/sleeves/scout/messages", headers=headers,
json={"message": "What changed in our market this week?"}).json()
while True:
answer = requests.get(f"{API}/messages/{msg['id']}", headers=headers, timeout=40).json()
if answer["done"]:
print(answer["text"] or answer["error"])
break
C# (.NET)
using System.Net.Http.Json;
var http = new HttpClient { BaseAddress = new Uri("https://api.sleevecast.com/v1/"), Timeout = TimeSpan.FromSeconds(40) };
http.DefaultRequestHeaders.Authorization = new("Bearer", "sc_...");
var sent = await http.PostAsJsonAsync("sleeves/scout/messages", new { message = "What changed in our market this week?" });
var id = (await sent.Content.ReadFromJsonAsync<Started>())!.Id;
Answer answer;
do answer = (await http.GetFromJsonAsync<Answer>($"messages/{id}"))!; while (!answer.Done);
Console.WriteLine(answer.Text ?? answer.Error);
record Started(string Id);
record Answer(string Id, bool Done, string? Text, string? Error);
Good to know
- A message is a task like any other: it uses tokens on your key and counts against the sleeve's guards.
- The audit log records each message with the key's name and the message's length, never its text.