REST API · v1

Selin API

Build AI-powered apps with the same intelligence behind Selin. Access streaming chat, image generation, voice, Canvas documents, and custom assistants — all through a single REST API.

Streaming Chat

SSE-based streaming with memory, web search, and tool use

Image & Video

Generate images and videos from natural language prompts

Deep Think

Extended reasoning mode for complex problems

bash
curl https://api.selin.ai/chat/message/stream \
  -H "Authorization: Bearer selin_sk_..." \
  -H "Content-Type: application/json" \
  -d '{"message": "Explain quantum entanglement simply"}'

Authentication

All API requests require a Bearer token in the Authorization header. Generate keys at /keys (Pro plan required).

http
Authorization: Bearer selin_sk_<your_key>

Keep keys secret. Never expose them in client-side code or public repositories. Rotate immediately if compromised.

Chat

Send messages and receive streaming responses via Server-Sent Events.

POST/chat/message/stream

Streams the response as SSE. Handles memory, web search, Deep Think, and custom assistants.

Request body

json
{
  "message":        "string (required)",
  "conversationId": "string (optional)",
  "assistantId":    "string (optional)",
  "projectId":      "string (optional)",
  "deepThink":      false,
  "imageBase64":    "string (optional)",
  "imageMediaType": "image/jpeg | image/png",
  "fileText":       "string (optional)",
  "fileName":       "string (optional)"
}

SSE event types

json
// New conversation ID
data: {"type":"conversation_id","conversationId":"..."}

// Text chunk
data: {"type":"text","text":"Hello"}

// Extended thinking chunk
data: {"type":"thinking","text":"Let me reason..."}

// Web search started
data: {"type":"search_start","query":"..."}

// Web search results
data: {"type":"search_done","sources":[...]}

// Stream complete
data: {"type":"done","domain":"...","emotion":"...","sources":[]}

// Error
data: {"type":"error","error":"message"}
javascript
const res = await fetch('https://api.selin.ai/chat/message/stream', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer selin_sk_...',
    'Content-Type':  'application/json',
  },
  body: JSON.stringify({ message: 'What is the Fermi paradox?' }),
});

const reader = res.body.getReader();
const decoder = new TextDecoder();

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

  const lines = decoder.decode(value).split('\n');
  for (const line of lines) {
    if (!line.startsWith('data: ')) continue;
    const event = JSON.parse(line.slice(6));
    if (event.type === 'text') process.stdout.write(event.text);
    if (event.type === 'done') console.log('\nDone.');
  }
}

Conversation management

GET/chat/conversationsList all conversations
GET/chat/conversations/:idGet a conversation with messages
PATCH/chat/conversations/:id/titleRename a conversation
DELETE/chat/conversations/:idDelete a conversation
POST/chat/conversations/:id/shareCreate a public share link

Media Generation

Generate images and videos from text prompts.

POST/media/imageGenerate an image — returns a CDN URL
POST/media/videoQueue a video generation job
GET/media/video/:idPoll video status (pending → completed)
GET/media/historyList generated media
json
// POST /media/image — request
{
  "prompt":         "A cherry blossom forest at dusk, Studio Ghibli style",
  "conversationId": "optional"
}

// Response
{
  "url":    "https://cdn.../image.jpg",
  "width":  1024,
  "height": 1024
}

Canvas Documents

Create and AI-assist documents in the Selin Canvas workspace.

GET/canvasList all documents
POST/canvasCreate a new document
GET/canvas/:idGet a document
PATCH/canvas/:idUpdate title or content
DELETE/canvas/:idDelete a document
POST/canvas/:id/assistAI assist — streams SSE text
json
// POST /canvas/:id/assist — request
{
  "instruction": "Make this paragraph more concise",
  "selection":   "Optional — selected text to operate on"
}

// SSE response (same format as chat stream)
data: {"type":"text","text":"Here is the revised..."}
data: {"type":"done"}

Custom Assistants

Create reusable assistants with custom instructions injected into every conversation.

GET/assistantsList your assistants
GET/assistants/publicBrowse public assistants
POST/assistantsCreate an assistant
PUT/assistants/:idUpdate an assistant
DELETE/assistants/:idDelete an assistant
json
// POST /assistants — create
{
  "name":         "Contract Reviewer",
  "emoji":        "⚖️",
  "instructions": "You are a senior legal analyst. Review contracts...",
  "basePersona":  "legal",
  "isPublic":     false
}

// Then use in chat
{
  "message":     "Review this NDA clause...",
  "assistantId": "<assistant_id>"
}

File Uploads

Parse text from PDF, DOCX, and XLSX files. The extracted text can then be sent as fileText in a chat message.

POST/upload/pdfParse PDF, DOCX, or XLSX — returns extracted text
POST/sttSpeech-to-text — multipart/form-data, field: audio
POST/ttsText-to-speech — returns audio/mpeg blob
bash
# Upload a DOCX file
curl https://api.selin.ai/upload/pdf \
  -H "Authorization: Bearer selin_sk_..." \
  -F "file=@contract.docx"

# Response
{
  "text":     "THIS AGREEMENT is entered into...",
  "pages":    null,
  "fileName": "contract.docx",
  "type":     "docx"
}

Errors

All errors return a JSON object with an error field.

400

Bad Request

Missing or invalid parameters

401

Unauthorized

Missing or invalid API key

403

Forbidden

Plan limit reached or feature not available

404

Not Found

Resource does not exist or belongs to another user

422

Unprocessable

File corrupt or could not be parsed

429

Rate Limited

200 requests / 15 min global limit

500

Server Error

Unexpected error — try again

json
// Error response shape
{
  "error":   "API keys require a Pro plan. Upgrade at selin.ai/settings.",
  "upgrade": true   // optional — present when a plan upgrade resolves the issue
}