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
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).
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.
/chat/message/streamStreams the response as SSE. Handles memory, web search, Deep Think, and custom assistants.
Request body
{
"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
// 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"}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
/chat/conversationsList all conversations/chat/conversations/:idGet a conversation with messages/chat/conversations/:id/titleRename a conversation/chat/conversations/:idDelete a conversation/chat/conversations/:id/shareCreate a public share linkMedia Generation
Generate images and videos from text prompts.
/media/imageGenerate an image — returns a CDN URL/media/videoQueue a video generation job/media/video/:idPoll video status (pending → completed)/media/historyList generated media// 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.
/canvasList all documents/canvasCreate a new document/canvas/:idGet a document/canvas/:idUpdate title or content/canvas/:idDelete a document/canvas/:id/assistAI assist — streams SSE text// 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.
/assistantsList your assistants/assistants/publicBrowse public assistants/assistantsCreate an assistant/assistants/:idUpdate an assistant/assistants/:idDelete an assistant// 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.
/upload/pdfParse PDF, DOCX, or XLSX — returns extracted text/sttSpeech-to-text — multipart/form-data, field: audio/ttsText-to-speech — returns audio/mpeg blob# 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.
400Bad Request
Missing or invalid parameters
401Unauthorized
Missing or invalid API key
403Forbidden
Plan limit reached or feature not available
404Not Found
Resource does not exist or belongs to another user
422Unprocessable
File corrupt or could not be parsed
429Rate Limited
200 requests / 15 min global limit
500Server Error
Unexpected error — try again
// 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
}