Complete reference for the Epsimo Agent Platform API v1.0
Base URL: https://api.epsimoagents.com
- Authentication
- HTTP Status Codes
- Error Handling
- Rate Limits
- Projects
- Assistants
- Threads
- Messages
- Files
- Credits & Billing
- Virtual Database
All API requests require authentication using JWT tokens.
Register a new user account.
Request:
{
"email": "user@example.com",
"password": "secure-password"
}Response (200):
{
"access_token": "eyJhbG...",
"token_type": "Bearer",
"expires_in": 3600,
"user": {
"email": "user@example.com",
"user_id": "usr_..."
}
}Authenticate and receive access token.
Request:
{
"email": "user@example.com",
"password": "secure-password"
}Response (200):
{
"access_token": "eyJhbG...",
"token": "eyJhbG...",
"jwt_token": "eyJhbG...",
"expires_in": 3600
}Error Response (401):
{
"error": "Invalid credentials",
"detail": "Email or password is incorrect"
}Get current user information and thread usage.
Headers:
Authorization: Bearer <access_token>
Response (200):
{
"email": "user@example.com",
"user_id": "usr_123",
"thread_counter": 45,
"thread_max": 100,
"subscription_tier": "standard"
}Tokens expire after 1 hour. To refresh:
# Python example
import requests
def refresh_token(expired_token):
# Re-authenticate with stored credentials
response = requests.post(
"https://api.epsimoagents.com/auth/login",
json={"email": stored_email, "password": stored_password}
)
return response.json()["access_token"]| Code | Meaning | Common Causes | Recommended Action |
|---|---|---|---|
| 200 | Success | Request completed successfully | Continue processing |
| 201 | Created | Resource created successfully | Capture returned ID |
| 204 | No Content | Deletion succeeded | Confirm success |
| 400 | Bad Request | Invalid payload, missing fields | Validate request schema |
| 401 | Unauthorized | Invalid/expired token | Refresh or re-authenticate |
| 403 | Forbidden | Insufficient permissions | Check user/project access |
| 404 | Not Found | Resource doesn't exist | Verify ID is correct |
| 409 | Conflict | Duplicate resource | Check for existing records |
| 422 | Validation Error | Schema validation failed | Review error details |
| 429 | Too Many Requests | Rate limit exceeded | Implement exponential backoff |
| 500 | Server Error | Backend issue | Retry with exponential backoff |
| 503 | Service Unavailable | Temporary downtime | Wait and retry |
{
"error": "Error type",
"detail": "Detailed error message",
"field": "problematic_field_name",
"code": "ERROR_CODE"
}Validation Error (422):
{
"error": "Validation Error",
"detail": "Field 'name' is required",
"field": "name"
}Authentication Error (401):
{
"error": "Unauthorized",
"detail": "Token has expired or is invalid",
"code": "TOKEN_EXPIRED"
}import time
import requests
from requests.exceptions import HTTPError
def make_request_with_retry(url, headers, method="GET", json_data=None, max_retries=5):
"""Make API request with automatic retry on rate limits and server errors."""
for attempt in range(max_retries):
try:
response = requests.request(method, url, headers=headers, json=json_data)
response.raise_for_status()
return response.json() if response.content else None
except HTTPError as e:
if e.response.status_code == 429:
# Rate limited - exponential backoff
wait_time = min(60 * (2 ** attempt), 300) # Max 5 minutes
print(f"Rate limited. Waiting {wait_time}s...")
time.sleep(wait_time)
elif e.response.status_code >= 500:
# Server error - retry with backoff
wait_time = min(10 * (2 ** attempt), 60) # Max 1 minute
print(f"Server error. Waiting {wait_time}s...")
time.sleep(wait_time)
elif e.response.status_code == 401:
# Token expired - try to refresh
print("Token expired. Attempting refresh...")
raise
else:
# Other errors - don't retry
raise
raise Exception(f"Max retries ({max_retries}) exceeded")| Tier | Limit |
|---|---|
| Free | 60 requests/minute |
| Standard | 300 requests/minute |
| Premium | 1,000 requests/minute |
Rate Limit Headers:
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 245
X-RateLimit-Reset: 1672531200
When rate limited (429), wait and retry with exponential backoff (see Error Handling).
Projects are top-level containers for assistants, threads, and files.
List all projects for the authenticated user.
Headers:
Authorization: Bearer <access_token>
Response (200):
[
{
"project_id": "proj_abc123",
"name": "My AI Project",
"description": "Customer support automation",
"created_at": "2024-01-15T10:30:00Z",
"access_token": "proj_token_..."
}
]Create a new project.
Request:
{
"name": "My New Project",
"description": "Optional description",
"metadata": {
"custom_field": "value"
}
}Response (201):
{
"project_id": "proj_xyz789",
"name": "My New Project",
"description": "Optional description",
"access_token": "proj_token_...",
"created_at": "2024-01-15T11:00:00Z"
}Get project details including project-specific access token.
Response (200):
{
"project_id": "proj_abc123",
"name": "My AI Project",
"description": "Customer support automation",
"access_token": "proj_token_...",
"token": "proj_token_...",
"jwt_token": "proj_token_...",
"created_at": "2024-01-15T10:30:00Z"
}Note: Use the access_token from this response for project-scoped operations (assistants, threads, files).
Delete a project and all associated resources.
Query Parameters:
confirm=true(required) - Confirmation flag
Response (204): No content (successful deletion)
Assistants are AI agents with specific instructions and capabilities.
List all assistants in a project.
Headers:
Authorization: Bearer <project_access_token>
Response (200):
[
{
"assistant_id": "asst_abc123",
"name": "Support Agent",
"config": {
"instructions": "You are a helpful support agent",
"model": "gpt-4o",
"configurable": {
"type": "agent",
"agent_type": "agent"
}
},
"public": false,
"created_at": "2024-01-15T10:45:00Z"
}
]Create a new assistant.
Request:
{
"name": "Research Assistant",
"config": {
"instructions": "You help with research tasks",
"model": "gpt-4o",
"configurable": {
"type": "agent",
"agent_type": "agent"
},
"tools": [
{
"type": "search_tavily",
"max_results": 5
},
{
"type": "function",
"name": "update_database",
"description": "Save structured data",
"parameters": {
"type": "object",
"properties": {
"key": {"type": "string"},
"value": {"type": "object"}
},
"required": ["key", "value"]
}
}
]
},
"public": false
}Response (201):
{
"assistant_id": "asst_xyz789",
"name": "Research Assistant",
"config": { ... },
"public": false,
"created_at": "2024-01-15T11:15:00Z"
}Get assistant details.
Response (200):
{
"assistant_id": "asst_abc123",
"name": "Support Agent",
"config": { ... },
"public": false,
"created_at": "2024-01-15T10:45:00Z"
}Delete an assistant.
Response (204): No content (successful deletion)
Threads represent persistent conversation contexts with Virtual Database state.
List all threads in a project.
Headers:
Authorization: Bearer <project_access_token>
Response (200):
[
{
"thread_id": "thread_abc123",
"name": "Customer #1234",
"assistant_id": "asst_xyz789",
"metadata": {
"configurable": {},
"type": "thread"
},
"created_at": "2024-01-15T12:00:00Z"
}
]Create a new thread.
Request:
{
"name": "Customer Support Session",
"assistant_id": "asst_xyz789",
"metadata": {
"configurable": {},
"type": "thread"
},
"configurable": {
"type": "agent"
}
}Response (201):
{
"thread_id": "thread_new123",
"name": "Customer Support Session",
"assistant_id": "asst_xyz789",
"created_at": "2024-01-15T12:30:00Z"
}Get thread details and messages.
Response (200):
{
"thread_id": "thread_abc123",
"name": "Customer #1234",
"assistant_id": "asst_xyz789",
"messages": [
{
"role": "user",
"content": "Hello!",
"timestamp": "2024-01-15T12:01:00Z"
},
{
"role": "assistant",
"content": "How can I help you?",
"timestamp": "2024-01-15T12:01:05Z"
}
]
}Send a message and stream the assistant's response.
Request:
{
"message": "What's the status of my order?",
"stream": true
}Response (Streaming):
data: {"type": "start", "run_id": "run_123"}
data: {"type": "content", "delta": "Your"}
data: {"type": "content", "delta": " order"}
data: {"type": "tool_call", "name": "database_query", "args": {...}}
data: {"type": "done"}
Delete a thread.
Response (204): No content (successful deletion)
Get all messages in a thread.
Query Parameters:
limit(optional): Max messages to return (default: 50)before(optional): Cursor for pagination
Response (200):
{
"messages": [
{
"message_id": "msg_123",
"role": "user",
"content": "Hello",
"timestamp": "2024-01-15T12:00:00Z"
}
],
"has_more": false
}Add a message to a thread (without triggering assistant).
Request:
{
"role": "user",
"content": "This is a manual message"
}Response (201):
{
"message_id": "msg_new456",
"role": "user",
"content": "This is a manual message",
"timestamp": "2024-01-15T12:45:00Z"
}List all files in a project.
Headers:
Authorization: Bearer <project_access_token>
Response (200):
[
{
"file_id": "file_abc123",
"filename": "document.pdf",
"size": 1024567,
"mime_type": "application/pdf",
"uploaded_at": "2024-01-15T13:00:00Z"
}
]Upload a file.
Request (multipart/form-data):
file: <binary file data>
purpose: "assistants" | "retrieval"
Response (201):
{
"file_id": "file_new789",
"filename": "document.pdf",
"size": 1024567,
"purpose": "retrieval",
"uploaded_at": "2024-01-15T13:15:00Z"
}Delete a file.
Response (204): No content (successful deletion)
Get current thread usage and limits.
Headers:
Authorization: Bearer <access_token>
Response (200):
{
"thread_counter": 45,
"thread_max": 100,
"threads_remaining": 55,
"subscription_tier": "standard"
}Create a Stripe checkout session for purchasing threads.
Request:
{
"quantity": 1000,
"amount": 80.00
}Response (200):
{
"url": "https://checkout.stripe.com/session_...",
"session_id": "cs_..."
}Pricing:
- < 500 threads: €0.10/thread
- 500-999 threads: €0.09/thread
- 1000+ threads: €0.08/thread
Threads can serve as structured, persistent storage.
Get all structured data from a thread.
Headers:
Authorization: Bearer <project_access_token>
Response (200):
{
"user_preferences": {
"theme": "dark",
"language": "en"
},
"status": "active",
"last_action": "checkout"
}Get specific key from thread state.
Response (200):
{
"theme": "dark",
"language": "en"
}Set a key-value pair in thread state.
Request:
{
"value": {
"theme": "light",
"language": "es"
}
}Response (200):
{
"success": true,
"key": "user_preferences",
"value": {
"theme": "light",
"language": "es"
}
}- Cache tokens and refresh on 401 errors
- Store tokens securely (never in version control)
- Use project-specific tokens for multi-tenant apps
- Always implement retry logic for 429 and 500+ errors
- Use exponential backoff with jitter
- Log errors for debugging
- Implement client-side throttling
- Respect
X-RateLimit-*headers - Consider upgrading tier for higher limits
- Use HTTPS for all requests
- Validate SSL certificates in production
- Never expose API keys in frontend code
- Use environment variables for credentials
- Use streaming for long-running conversations
- Implement pagination for large result sets
- Cache frequently accessed data
- Batch operations when possible
See README.md for comprehensive Python SDK examples.
- GitHub Issues: https://github.com/thierryteisseire/epsimo-agent/issues
- Documentation: SKILL.md
- Virtual DB Guide: docs/virtual_db_guide.md
API Version: 1.0
Last Updated: 2024-02-11