Space reference
Base URL: https://api.space.destesi.io
Authentication
Section titled “Authentication”Two ways in, and Space accepts no others.
Browser session. Signing in through SSO sets a
host-only space_session cookie on the API host. This is what the web app
uses; send it with credentials included.
Personal Access Token. For the CLI, scripts and MCP, send an identity PAT plus the workspace slug:
Authorization: Bearer idn_pat_…X-Destesi-Workspace: acme-coBoth headers are required on the token path — a PAT is scoped to a user, and the workspace is chosen per request. See CLI & API auth for minting a token.
Vocabularies
Section titled “Vocabularies”| Field | Values |
|---|---|
| Issue status | backlog, todo, in_progress, in_review, done, cancelled |
| Issue priority | none, low, medium, high, urgent |
| Channel visibility | public, private |
| Team key | 2–6 chars, ^[A-Z][A-Z0-9]{1,5}$ |
| Label color | #rrggbb, defaults to #6b7280 |
Any status may move to any other; there is no transition table.
Endpoints
Section titled “Endpoints”Session
Section titled “Session”| Method | Path | Purpose |
|---|---|---|
GET |
/healthz |
Liveness. Public |
GET |
/v1/sso/callback |
SSO landing; sets space_session. Public |
GET |
/v1/auth/me |
The signed-in user |
POST |
/v1/auth/logout |
Clears the session. Idempotent |
GET |
/v1/me/products |
Launcher entitlements, proxied from identity |
Teams, members and labels
Section titled “Teams, members and labels”| Method | Path | Purpose |
|---|---|---|
GET |
/v1/teams |
Teams with id, key, name |
POST |
/v1/teams |
Create a team |
GET |
/v1/members |
Workspace members: user_id, name, role |
GET |
/v1/labels |
Labels |
POST |
/v1/labels |
Create a label (name, optional color) |
Issues
Section titled “Issues”| Method | Path | Purpose |
|---|---|---|
GET |
/v1/issues |
List, newest first |
POST |
/v1/issues |
Create. Requires team_id and title |
GET |
/v1/issues/{id} |
One issue |
PATCH |
/v1/issues/{id} |
Update. Omitted fields are left alone |
DELETE |
/v1/issues/{id} |
Delete |
GET |
/v1/issues/{id}/messages |
The issue’s thread |
POST |
/v1/issues/{id}/messages |
Comment on the issue |
GET /v1/issues filters, all optional and combined with AND:
| Param | Meaning |
|---|---|
team |
Team id |
status |
Comma-separated or repeated; each value validated |
assignee |
User id |
creator |
User id |
label |
Label id |
Every issue response carries the rendered key (ENG-12) alongside
team_key and number. Use the key when showing an issue to a person.
On PATCH, assignee_user_id has three states: absent leaves the
assignee alone, a string assigns, and a JSON null clears it. Sending
an empty string is not the same as sending null.
Channels and direct messages
Section titled “Channels and direct messages”| Method | Path | Purpose |
|---|---|---|
GET |
/v1/channels |
Channels you can see. ?archived=true includes archived |
POST |
/v1/channels |
Create (name, optional purpose, visibility, members) |
GET |
/v1/channels/{id} |
One channel |
PATCH |
/v1/channels/{id} |
Rename, re-purpose, or archive |
POST |
/v1/channels/{id}/members |
Add members (private channels) |
DELETE |
/v1/channels/{id}/members/{user} |
Remove a member |
GET |
/v1/dms |
Your direct messages |
POST |
/v1/dms |
Open a DM with another member |
Messages
Section titled “Messages”Issue threads, channels and DMs are all threads, so these routes serve all three. The issue-scoped message routes above are a facade over these.
| Method | Path | Purpose |
|---|---|---|
GET |
/v1/threads/{id}/messages |
Messages, newest first |
POST |
/v1/threads/{id}/messages |
Post. Body 1–50000 chars |
GET |
/v1/threads/{id}/messages/{mid}/replies |
Replies to one message |
PUT |
/v1/threads/{id}/read |
Mark the thread read |
PATCH |
/v1/messages/{id} |
Edit your own message |
DELETE |
/v1/messages/{id} |
Delete your own message |
PUT |
/v1/messages/{id}/reactions/{emoji} |
React (emoji 1–32 chars) |
DELETE |
/v1/messages/{id}/reactions/{emoji} |
Remove your reaction |
GET |
/v1/unread |
Per-thread unread and mention counts |
Assistant
Section titled “Assistant”| Method | Path | Purpose |
|---|---|---|
POST |
/v1/chat |
Streams NDJSON; pauses on an approval-gated tool |
POST |
/v1/chat/resume |
Approve or reject the one held tool call |
GET |
/v1/conversations |
Your conversations |
GET |
/v1/conversations/{id}/messages |
One conversation’s history |
PATCH |
/v1/conversations/{id} |
Rename |
DELETE |
/v1/conversations/{id} |
Delete |
The assistant’s tools are list_teams, list_members, list_issues,
get_issue, list_channels, list_unread, read_thread, create_issue,
update_issue, create_channel and post_message. Only post_message
requires approval.
Without a model provider configured for the deployment, /v1/chat answers
503 chat_disabled. Without conversation persistence, the history routes
answer 503 persistence_disabled and chat runs statelessly.
Live updates
Section titled “Live updates”| Method | Path | Purpose |
|---|---|---|
GET |
/v1/stream |
Server-sent events for the workspace |
Event kinds: issue.created, issue.updated, issue.deleted,
message.created, message.updated, message.deleted, reaction.updated,
channel.created, dm.created.
Where live delivery is not configured the endpoint answers 503 live_disabled, and clients should poll instead of reconnecting.
Error codes
Section titled “Error codes”Errors are {"error":"code"}, sometimes with a detail.
| Code | Status | Meaning |
|---|---|---|
missing_session |
401 | No cookie and no bearer |
session_invalid |
401 | Cookie rejected by identity; it is cleared |
unknown_bearer_scheme |
401 | Bearer is not an idn_pat_ PAT |
missing_workspace_header |
401 | PAT sent without X-Destesi-Workspace |
invalid_token |
401 | PAT unknown, or not a member of that workspace |
csrf_rejected |
403 | Cookie mutation from an untrusted origin |
not_found |
404 | Unknown id — or one in another workspace |
missing_team |
422 | team_id is required to create an issue |
invalid_title |
422 | Title must be 1–500 characters |
invalid_status / invalid_priority |
422 | Outside the vocabulary |
invalid_visibility |
422 | Channel visibility is public or private |
invalid_key |
422 | Team key fails ^[A-Z][A-Z0-9]{1,5}$ |
invalid_color |
422 | Label color is not #rrggbb |
invalid_message |
422 | Message body must be 1–50000 characters |
invalid_emoji |
422 | Emoji must be 1–32 characters |
team_key_taken / label_name_taken / channel_name_taken |
409 | Name already used in this workspace |
channel_archived |
409 | Archived channels are read-only |
chat_disabled |
503 | No model provider configured |
live_disabled |
503 | Live delivery not configured — poll instead |
members_disabled |
503 | Member directory not configured |
quota_check_failed |
503 | The quota policy could not be answered |
identity_unavailable |
502 | Identity could not be reached |
Quotas
Section titled “Quotas”| Capability | Counts |
|---|---|
max_open_issues |
Issues not done or cancelled |
max_hu_per_month |
Monthly assistant model spend |
Both are measured in record mode — shown, not enforced. See
Entitlements.
MCP tools
Section titled “MCP tools”Available to an AI coding agent on Destesi’s hosted full-suite MCP server at
https://mcp.destesi.io/sse, and on any mcp binary you run yourself with
SPACE_API_URL set. See MCP. Every tool takes a workspace slug, and
accepts a human key (ENG-12, ENG) wherever an issue or team is named.
| Tool | Purpose |
|---|---|
space_list_teams |
Teams with their keys |
space_list_members |
People, to turn a name into a user id |
space_list_issues |
List, filtered by team, status, assignee, creator |
space_get_issue |
One issue by key or id |
space_create_issue |
Open a ticket |
space_update_issue |
Change status, priority, title, description, assignee |
space_comment_issue |
Comment on the issue’s thread |
dst space needs an identity PAT and a workspace. See
CLI for install and login.
dst space teams # keys, names, idsdst space members # user ids for --assignee
dst space issue create "Checkout drops the cart" --team ENGdst space issue create --team ENG --title "Flaky test" --priority high
dst space issues --status todo,in_progress # also: dst space issue listdst space issue show ENG-12 --commentsdst space issue update ENG-12 --status in_progressdst space issue update ENG-12 --unassigndst space issue comment ENG-12 "Reproduced on main."git log -1 --format=%B | dst space issue comment ENG-12 ---team may be omitted when the workspace has exactly one team. Every
subcommand takes -o json.
The base URL is derived from your configured API URL and can be overridden
with --space-api-url or DESTESI_SPACE_API_URL.