Authentication
All AI endpoints require an API key and bundle ID in the request headers:
X-API-Key: sa_your_api_key
X-Bundle-ID: com.example.myapp
Content-Type: application/json
Note: API keys start with sa_ and are at least 20 characters long. Obtain yours from the developer console.
Endpoints Overview
| Method | Endpoint | Description |
|---|---|---|
| POST | /v1/ai/chat | Chat completion |
| POST | /v1/ai/stream | SSE streaming chat |
| POST | /v1/ai/images | Image generation |
| POST | /v1/ai/tokens | Token counting |
| GET | /v1/ai/models | List available models |
| GET | /health | Health check (no auth) |
POST /v1/ai/chat
Send a chat completion request:
curl -X POST https://api.getswiftly.ai/v1/ai/chat \
-H "X-API-Key: sa_your_api_key" \
-H "X-Bundle-ID: com.yourapp" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-5-20250929",
"messages": [{
"role": "user",
"content": [{"type": "text", "text": "Hello!"}]
}]
}'
Important: The content field must be an array of content objects, e.g. [{"type": "text", "text": "..."}], not a plain string.
POST /v1/ai/stream
Stream chat responses via Server-Sent Events (SSE):
curl -X POST https://api.getswiftly.ai/v1/ai/stream \
-H "X-API-Key: sa_your_api_key" \
-H "X-Bundle-ID: com.yourapp" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-5-20250929",
"messages": [{
"role": "user",
"content": [{"type": "text", "text": "Tell me a story"}]
}],
"stream": true
}'
Response format: data: {"message": "...", "model": "...", ...} lines, terminated by data: [DONE]
POST /v1/ai/images
Generate images from text prompts:
curl -X POST https://api.getswiftly.ai/v1/ai/images \
-H "X-API-Key: sa_your_api_key" \
-H "X-Bundle-ID: com.yourapp" \
-H "Content-Type: application/json" \
-d '{
"prompt": "A sunset over the mountains",
"model": "dall-e-3"
}'
POST /v1/ai/tokens
Count tokens for a set of messages:
curl -X POST https://api.getswiftly.ai/v1/ai/tokens \
-H "X-API-Key: sa_your_api_key" \
-H "X-Bundle-ID: com.yourapp" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-5-20250929",
"messages": [{
"role": "user",
"content": [{"type": "text", "text": "Hello!"}]
}]
}'
GET /v1/ai/models
List all available models grouped by provider:
curl https://api.getswiftly.ai/v1/ai/models \
-H "X-API-Key: sa_your_api_key" \
-H "X-Bundle-ID: com.yourapp"
GET /health
Check API server health (no authentication required):
curl https://api.getswiftly.ai/health
Error Codes
| Status | Code | Description |
|---|---|---|
| 400 | INVALID_REQUEST | Malformed request body |
| 401 | UNAUTHORIZED | Invalid or missing API key |
| 403 | FORBIDDEN | Bundle ID not registered |
| 429 | RATE_LIMITED | Too many requests |
| 402 | QUOTA_EXCEEDED | Monthly quota exceeded |
| 500 | SERVER_ERROR | Internal server error |
| 503 | PROVIDER_UNAVAILABLE | AI provider is down |
Quota Headers
Every API response includes quota information in the headers:
X-RateLimit-Limit: 50000 // Monthly request limit
X-RateLimit-Remaining: 49850 // Requests remaining
X-RateLimit-Reset: 1717200000 // Unix timestamp of reset