SLEEVECAST

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.