Integration Examples
Learn how to integrate CID222 into your applications with these real-world code examples across different languages and frameworks.
Responses stream as SSE
/chat/completions and session messages always return Server-Sent Events — read the stream and accumulate the content field of events that carry one; the complete filtered answer arrives as a single filtered-response event. There is no choices[] JSON body.
JavaScript / Node.js
Basic Request
Node.js - Collect the stream
1async function chat(userMessage) {2 const res = await fetch('https://api.cid222.ai/chat/completions', {3 method: 'POST',4 headers: {5 'Authorization': `Bearer ${process.env.CID222_API_KEY}`,6 'Content-Type': 'application/json',7 },8 body: JSON.stringify({9 model: 'gpt-4o',10 messages: [11 { role: 'system', content: 'You are a helpful assistant.' },12 { role: 'user', content: userMessage }13 ]14 })15 });1617 // /chat/completions always streams Server-Sent Events18 const reader = res.body.getReader();19 const decoder = new TextDecoder();20 let answer = '';2122 while (true) {23 const { done, value } = await reader.read();24 if (done) break;25 for (const line of decoder.decode(value).split('\n')) {26 if (!line.startsWith('data: ')) continue;27 const data = line.slice(6);28 if (data === '[DONE]') return answer;29 const event = JSON.parse(data);30 // Input blocked (type: "content_rejected")31 if (event.error) throw new Error('Blocked: ' + event.error);32 // Model text: top-level "content" string. The full filtered answer33 // arrives as one event (id: "filtered-response", finish_reason: "stop").34 if (!event.type && typeof event.content === 'string') {35 answer = event.finish_reason === 'stop' ? event.content : answer + event.content;36 }37 }38 }39 return answer;40}
Streaming Response
Node.js - Stream tokens & filter events
1async function streamChat(message, onToken) {2 const res = await fetch('https://api.cid222.ai/chat/completions', {3 method: 'POST',4 headers: {5 'Authorization': `Bearer ${process.env.CID222_API_KEY}`,6 'Content-Type': 'application/json',7 },8 body: JSON.stringify({9 model: 'gpt-4o',10 messages: [{ role: 'user', content: message }]11 })12 });1314 const reader = res.body.getReader();15 const decoder = new TextDecoder();1617 while (true) {18 const { done, value } = await reader.read();19 if (done) break;20 for (const line of decoder.decode(value).split('\n')) {21 if (!line.startsWith('data: ')) continue;22 const data = line.slice(6);23 if (data === '[DONE]') return;2425 const event = JSON.parse(data);26 // Input blocked before reaching the provider (type: "content_rejected")27 if (event.error) throw new Error('Blocked: ' + event.error);2829 switch (event.type) {30 case 'user_message_processed':31 // PII in the prompt was masked/flagged before sending32 console.warn('Prompt filtered:', event.masked_count, 'masked,',33 event.flagged_count, 'flagged');34 break;35 case 'output_content_rejected':36 throw new Error('Blocked: ' + event.reason);37 case 'output_content_warning':38 console.warn('Warning:', event.message);39 break;40 case undefined:41 // Model text — the complete filtered answer arrives as one event42 // (id: "filtered-response", finish_reason: "stop")43 if (typeof event.content === 'string') onToken(event.content);44 break;45 }46 }47 }48}
Python
Python - Stream with requests
1import os2import json3import requests45def stream_chat(message: str) -> str:6 response = requests.post(7 'https://api.cid222.ai/chat/completions',8 headers={9 'Authorization': f'Bearer {os.environ["CID222_API_KEY"]}',10 'Content-Type': 'application/json',11 },12 json={13 'model': 'gpt-4o',14 'messages': [{'role': 'user', 'content': message}],15 },16 stream=True,17 )1819 answer = ''20 for line in response.iter_lines():21 if not line:22 continue23 line = line.decode('utf-8')24 if not line.startswith('data: '):25 continue26 data = line[6:]27 if data == '[DONE]':28 break29 event = json.loads(data)30 if 'error' in event: # input blocked (type "content_rejected")31 raise RuntimeError('Blocked: ' + event['error'])32 if event.get('type') == 'output_content_rejected':33 raise RuntimeError('Blocked: ' + str(event.get('reason', '')))34 if not event.get('type') and isinstance(event.get('content'), str):35 # Model text. The complete filtered answer arrives as one event36 # (id "filtered-response", finish_reason "stop").37 if event.get('finish_reason') == 'stop':38 answer = event['content']39 else:40 answer += event['content']41 print(event['content'], end='', flush=True)42 print()43 return answer4445# Usage46stream_chat("Explain quantum computing in simple terms.")
Standalone Detection
Python - Scan text without an LLM
1import os2import requests34def detect(text: str) -> dict:5 response = requests.post(6 'https://api.cid222.ai/api/v1/guardrails/detect',7 headers={8 'Authorization': f'Bearer {os.environ["CID222_API_KEY"]}',9 'Content-Type': 'application/json',10 },11 json={'text': text, 'check_type': 'prompt'},12 )13 return response.json()1415result = detect("Email me at john@example.com")16print(result['action']) # e.g. "mask"17print(result['maskedText']) # "Email me at [EMAIL]"
React / Next.js
React - Chat Hook
1import { useState, useCallback } from 'react';23export function useChat() {4 const [messages, setMessages] = useState([]);5 const [isLoading, setIsLoading] = useState(false);67 const sendMessage = useCallback(async (content: string) => {8 setIsLoading(true);9 const userMessage = { role: 'user', content };10 setMessages(prev => [...prev, userMessage]);1112 try {13 // Your server route proxies CID222 and forwards the SSE stream14 const res = await fetch('/api/chat', {15 method: 'POST',16 headers: { 'Content-Type': 'application/json' },17 body: JSON.stringify({ messages: [...messages, userMessage] })18 });1920 const reader = res.body.getReader();21 const decoder = new TextDecoder();22 let answer = '';23 setMessages(prev => [...prev, { role: 'assistant', content: '' }]);2425 while (true) {26 const { done, value } = await reader.read();27 if (done) break;28 for (const line of decoder.decode(value).split('\n')) {29 if (!line.startsWith('data: ')) continue;30 const data = line.slice(6);31 if (data === '[DONE]') break;32 const event = JSON.parse(data);33 if (event.error) throw new Error('Blocked: ' + event.error);34 if (!event.type && typeof event.content === 'string') {35 // Full filtered answer arrives as one event (finish_reason: "stop")36 answer = event.finish_reason === 'stop' ? event.content : answer + event.content;37 setMessages(prev => {38 const next = [...prev];39 next[next.length - 1] = { role: 'assistant', content: answer };40 return next;41 });42 }43 }44 }45 } catch (error) {46 console.error('Chat error:', error);47 } finally {48 setIsLoading(false);49 }50 }, [messages]);5152 return { messages, sendMessage, isLoading };53}
For production React apps, consider using the CID222 SDK which handles streaming, error recovery, and type safety automatically.
cURL Examples
cURL - Basic Request
curl -N -X POST https://api.cid222.ai/chat/completions \-H "Authorization: Bearer $CID222_API_KEY" \-H "Content-Type: application/json" \-d '{"model": "gpt-4o","messages": [{"role": "user", "content": "Hello, world!"}]}'
cURL - Create Session (JWT)
# Create a session (sessions use a user JWT)curl -X POST https://api.cid222.ai/sessions \-H "Authorization: Bearer $CID222_JWT" \-H "Content-Type: application/json" \-d '{"session_name": "Demo","user_id": "user-123"}'# Send a message — choose the model per messagecurl -N -X POST https://api.cid222.ai/sessions/SESSION_ID/messages \-H "Authorization: Bearer $CID222_JWT" \-H "Content-Type: application/json" \-d '{"content": "What can you help me with?", "model": "gpt-4o"}'