dot-cOS API Reference
Base URL:
https://cos-api.dotevolve.netAll authenticated endpoints require
Authorization: Bearer <JWT>header (Supabase session token). Public endpoints are marked with 🔓.
1. Health Check Endpoints
All backend services expose a /health endpoint for infrastructure monitoring. These are consumed by the Platform Metrics page in the Admin Dashboard (/#/metrics).
| Service | URL | Method | Endpoint | Auth | Response |
|---|---|---|---|---|---|
| API Gateway | https://cos-api.dotevolve.net |
GET |
/health |
🔓 | { "service": "api-gateway", "status": "healthy" } |
| Workflow Service | https://cos-workflow.dotevolve.net |
GET |
/health |
🔓 | { "service": "workflow-service", "status": "healthy", "database": "connected" } |
Note: The Workflow Service health check also verifies database connectivity by executing
SELECT 1against PostgreSQL via Prisma. If the DB is down, it returns500with{ "status": "unhealthy", "error": "..." }.
2. Subscription Plans & Entity Types
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET |
/api/v1/plans |
🔓 | Returns subscription tiers (FREE, STARTER, PROFESSIONAL, ENTERPRISE) and Indian entity type taxonomy |
Response:
{
"data": {
"plans": [
{ "id": "FREE", "name": "Free", "monthlyPrice": 0, "limits": { "entities": 1, "users": 2, "workflows": 5 }, "features": [...] }
],
"entityTypes": [
{ "value": "PRIVATE_LIMITED", "label": "Private Limited Company" }
]
}
}
3. Tenant Management
| Method | Endpoint | Auth | Description |
|---|---|---|---|
POST |
/api/v1/tenants/signup |
🔓 | Self-service tenant registration (creates Supabase Auth user + tenant atomically) |
POST |
/api/v1/tenants |
🔒 | Admin-created tenant |
GET |
/api/v1/tenants |
🔒 | List all tenants |
POST /api/v1/tenants/signup (Public)
{
"organizationName": "Acme Corp Pvt Ltd",
"entityType": "PRIVATE_LIMITED",
"email": "admin@acme.com",
"password": "securePass123",
"phone": "+919876543210",
"gstin": "29AABCU9603R1ZM",
"pan": "AABCU9603R"
}
POST /api/v1/tenants (Admin)
{
"name": "Beta Industries LLP",
"entityType": "LLP",
"contactEmail": "cs@beta.in",
"contactPhone": "+911234567890",
"gstin": "27AADCB2230M1ZT",
"pan": "AADCB2230M",
"registrationNumber": "AAA-1234",
"subscriptionPlan": "STARTER"
}
4. Workflow Templates
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET |
/api/v1/workflows/templates |
🔒 | List all workflow templates |
POST |
/api/v1/workflows/templates |
🔒 | Create a workflow template |
PUT |
/api/v1/workflows/templates/:id |
🔒 | Update template phases |
Template Structure
{
"workflowName": "Annual General Meeting (AGM)",
"legalReference": "Companies Act 2013, Section 96; SS-2",
"applicabilityRules": {
"entityTypes": ["PRIVATE_LIMITED", "PUBLIC_LIMITED"]
},
"timelineLogic": {
"triggerDate": "financial_year_end",
"deadlineDays": 180,
"reminderDaysBefore": [60, 30, 14, 7]
},
"phases": [
{
"name": "Pre-AGM Preparation",
"order": 1,
"tasks": [
{
"name": "Finalize audited financial statements",
"mandatory": true,
"advisory": "Balance Sheet, P&L must be approved by Board."
}
]
}
],
"validationRules": { "requiresAuditedFinancials": true },
"advisoryPrompts": { "stampPaper": "Not required for AGM resolutions." },
"completionCriteria": {
"allMandatoryTasksCompleted": true,
"filingConfirmation": ["AOC-4", "MGT-7"]
}
}
5. Workflow Instances
| Method | Endpoint | Auth | Description |
|---|---|---|---|
POST |
/api/v1/workflows/instances |
🔒 | Create an instance from a template (assign to tenant + entity) |
GET |
/api/v1/workflows/instances?tenantId= |
🔒 | List all instances for a tenant |
GET |
/api/v1/workflows/instances/:id |
🔒 | Get instance detail with template, entity, tenant |
PATCH |
/api/v1/workflows/instances/:id/tasks |
🔒 | Toggle a task's completion status |
POST |
/api/v1/workflows/instances/:id/generate-pdf |
🔒 | Generate a PDF compliance certificate |
POST /api/v1/workflows/instances — Create Instance
{
"tenantId": "uuid-of-tenant",
"templateId": "uuid-of-template",
"entityId": "uuid-of-entity"
}
The API copies all phases/tasks from the template into currentData and sets status to IN_PROGRESS.
PATCH /api/v1/workflows/instances/:id/tasks — Toggle Task
{
"taskId": "p1_t3",
"completed": true
}
When all mandatory tasks are completed, the instance auto-transitions to COMPLETED.
6. Document Templates
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET |
/api/v1/documents/templates |
🔒 | List all templates (filter: ?category=BOARD_RESOLUTION&tenantId=) |
GET |
/api/v1/documents/templates/:id |
🔒 | Get template with full HTML body + metadata (includes postSteps) |
POST |
/api/v1/documents/templates |
🔒 | Create a document template |
PATCH |
/api/v1/documents/templates/:id |
🔒 | Update template metadata, name, body, or variables |
POST |
/api/v1/documents/generate/:templateId |
🔒 | Render template with variable substitution |
GET /api/v1/documents/templates — List Templates
Returns templates without the body field for efficiency.
Query Parameters:
category— Filter by category (BOARD_RESOLUTION,NOTICE,LETTER,DISCLOSURE,CERTIFICATE,MINUTES,SEBI_DISCLOSURE)tenantId— Returns global templates (tenantId = null) + tenant-specific ones
POST /api/v1/documents/generate/:templateId — Render Document
{
"companyName": "Acme Corp Pvt Ltd",
"cin": "U12345MH2020PTC123456",
"meetingDate": "23rd February, 2026",
"auditorName": "M/s Sharma & Associates",
"auditorFRN": "123456N",
"chairmanName": "Mr. Rajesh Kumar"
}
Response:
{
"message": "Document generated successfully",
"data": {
"templateName": "Board Resolution — Appointment of Statutory Auditor",
"category": "BOARD_RESOLUTION",
"legalReference": "Section 139, Companies Act 2013",
"renderedHtml": "<div style='...'>...full rendered HTML...</div>"
}
}
Template Metadata — postSteps
Each template's metadata field contains a postSteps array defining the post-generation document lifecycle (returned by GET /documents/templates/:id):
{
"filingForm": "ADT-1",
"filingDeadline": "15 days from AGM",
"signatories": ["Chairman"],
"postSteps": [
{
"order": 1,
"icon": "🖊️",
"title": "Obtain Director Signatures",
"description": "Get the resolution signed by the Chairman.",
"type": "SIGNING",
"mandatory": true
},
{
"order": 2,
"icon": "📜",
"title": "Print on Stamp Paper",
"description": "Print on non-judicial stamp paper.",
"type": "STAMP_PAPER",
"mandatory": true,
"stampDenomination": "₹100–₹500"
},
{
"order": 3,
"icon": "📝",
"title": "File Form ADT-1 with ROC",
"description": "File within 15 days of AGM.",
"type": "FILING",
"mandatory": true
}
]
}
Step Types: SIGNING, CERTIFICATION, STAMP_PAPER, FILING, STORAGE, DISTRIBUTION, REMINDER
7. Intelligent Document Processing (IDP)
| Method | Endpoint | Auth | Description |
|---|---|---|---|
POST |
/api/v1/documents/process |
🔒 | Upload a document for AI-powered OCR extraction |
POST |
/api/v1/documents/verification/save |
🔒 | Save human-verified extracted data to database |
POST /api/v1/documents/process — Upload & Extract
Accepts multipart/form-data with a file upload. The backend sends the document to OpenAI GPT-4o for structured data extraction based on the detected document category.
Supported Document Categories:
| Category | Description |
|---|---|
INCORPORATION_CERT |
Certificate of Incorporation |
GST_CERTIFICATE |
GST Registration Certificate |
PAN_CARD |
PAN Card (Company/Individual) |
BOARD_RESOLUTION |
Board Resolution Document |
FINANCIAL_STATEMENT |
Balance Sheet / P&L Statement |
ANNUAL_RETURN |
Annual Return Filing (MGT-7) |
DIRECTOR_KYC |
Director KYC Document (DIR-3 KYC) |
OTHER |
Any other document |
Response:
{
"data": {
"category": "INCORPORATION_CERT",
"extractedFields": {
"companyName": "Acme Corp Pvt Ltd",
"cin": "U12345MH2020PTC123456",
"dateOfIncorporation": "15/01/2020"
},
"confidence": 0.95
}
}
8. Document Vault
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET |
/api/v1/documents/vault |
🔒 | List all uploaded documents for the tenant |
POST |
/api/v1/documents/vault/upload |
🔒 | Upload a document to Supabase Storage |
GET |
/api/v1/documents/vault/:id |
🔒 | Get document metadata and signed download URL |
9. Entity Management
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET |
/api/v1/entities?tenantId= |
🔒 | List entities for a tenant |
POST |
/api/v1/entities |
🔒 | Create a new entity under a tenant |
PATCH |
/api/v1/entities/:id |
🔒 | Update entity details including profileData |
GET |
/api/v1/entities/:id |
🔒 | Get entity with full profileData for auto-fill |
Entity profileData Structure
The profileData JSON field stores comprehensive company information used for document template auto-fill:
{
"registeredAddress": "123 MG Road, Mumbai 400001",
"cin": "U12345MH2020PTC123456",
"dateOfIncorporation": "15/01/2020",
"authorizedCapital": "10,00,000",
"paidUpCapital": "5,00,000",
"directors": [
{
"name": "Rajesh Kumar",
"din": "01234567",
"designation": "Managing Director"
}
]
}
10. Database Schema
Models
| Model | Description |
|---|---|
Tenant |
SaaS client organization with entity type, contact info, tax IDs, subscription plan |
Entity |
Business unit within a tenant |
User |
User account linked to Supabase Auth |
Role |
RBAC role definitions |
WorkflowTemplate |
Blueprint for compliance checklists (phases, tasks, legal refs) |
WorkflowInstance |
Live execution of a template assigned to a tenant + entity |
DocumentTemplate |
Reusable HTML document template with {{variable}} placeholders |
FinancialMetric |
Tracked financial data points for threshold monitoring |
AuditLog |
Immutable record of all state changes |
11. User Context Resolution
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET |
/api/v1/me?email= |
🔒 | Resolve user context (tenant, entity, role) |
GET /api/v1/me — Get User Context
Query Parameters:
email(required) - User's email address
Response:
{
"data": {
"id": "user-uuid",
"name": "John Doe",
"email": "john@acme.com",
"tenant": {
"id": "tenant-uuid",
"name": "Acme Corp",
"subscriptionPlan": "FREE"
},
"entity": {
"id": "entity-uuid",
"name": "Acme Ltd"
},
"role": {
"id": "role-uuid",
"name": "Company Secretary",
"permissions": {}
}
}
}
12. ERP Webhook Integration
| Method | Endpoint | Auth | Description |
|---|---|---|---|
POST |
/api/v1/webhooks/erp |
🔓 | Receive ERP metric events (async via QStash / queue) |
POST /api/v1/webhooks/erp — ERP Metric Event
Request Body:
{
"tenantId": "uuid",
"entityId": "uuid",
"metricType": "Turnover",
"metricValue": 50000000
}
Response (202 Accepted):
{
"message": "Metric event accepted and pushed to processing queue",
"queued": true,
"referenceId": "tenant-uuid-1234567890"
}
Supported Metric Types:
Turnover- Annual revenuePaid-up Capital- Paid-up share capitalNet Worth- Total assets minus liabilitiesBorrowings- Total debt
13. Authentication
JWT Token Structure
All authenticated requests require a JWT token from Supabase Auth:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Token Claims:
{
"sub": "user-uuid",
"email": "user@example.com",
"user_metadata": {
"tenantId": "tenant-uuid",
"entityId": "entity-uuid"
},
"iat": 1234567890,
"exp": 1234567890
}
Token Acquisition
Frontend (Supabase Client):
const { data, error } = await supabase.auth.signInWithPassword({
email: "user@example.com",
password: "password",
});
const token = data.session.access_token;
API Requests:
const response = await axios.get("/api/v1/workflows/templates", {
headers: {
Authorization: `Bearer ${token}`,
},
});
14. Error Responses
All endpoints return errors in a consistent format:
{
"error": "Human-readable error message",
"code": "ERROR_CODE",
"details": {
"field": "Additional context"
}
}
Standard Error Codes
| HTTP Status | Error Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR |
Invalid request data |
| 401 | UNAUTHORIZED |
Missing or invalid authentication token |
| 403 | FORBIDDEN |
Insufficient permissions |
| 404 | NOT_FOUND |
Resource not found |
| 409 | CONFLICT |
Resource conflict (e.g., duplicate entry) |
| 429 | RATE_LIMIT_EXCEEDED |
Too many requests |
| 500 | INTERNAL_ERROR |
Internal server error |
| 503 | SERVICE_UNAVAILABLE |
Service temporarily unavailable |
15. Rate Limiting
Current Limits:
- 100 requests per 15 minutes per IP address
- 1000 requests per hour per authenticated user
Rate Limit Headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1234567890
Rate Limit Exceeded Response (429):
{
"error": "Too many requests. Please try again later.",
"code": "RATE_LIMIT_EXCEEDED",
"retryAfter": 60
}
16. Pagination
List endpoints support pagination via query parameters:
Query Parameters:
page(number) - Page number (1-indexed, default: 1)limit(number) - Items per page (default: 20, max: 100)
Response Format:
{
"data": [...],
"pagination": {
"page": 1,
"limit": 20,
"total": 100,
"totalPages": 5
}
}
17. Filtering and Sorting
Filtering
Use query parameters to filter results:
GET /api/v1/workflows/templates?tenantId=uuid&isActive=true
GET /api/v1/documents/templates?category=BOARD_RESOLUTION
Sorting
Use the sort query parameter:
GET /api/v1/tenants?sort=createdAt:desc
GET /api/v1/workflows/instances?sort=status:asc,createdAt:desc
Sort Format: field:direction where direction is asc or desc
18. Deployed Services
| Service | URL | Repository |
|---|---|---|
| API Gateway | https://cos-api.dotevolve.net |
DotEvolve/dot-cos-api-gateway |
| Workflow Service | https://cos-workflow.dotevolve.net |
DotEvolve/dot-cos-workflow-service |
| Admin Dashboard | https://cos-admin.dotevolve.net |
DotEvolve/dot-cos-admin-dashboard |
| Client Portal | https://cos.dotevolve.net |
DotEvolve/dot-cos-frontend |
| Documentation | — | DotEvolve/dot-cos |
Related documentation
10. Document Workflow Standardization APIs
10.1 Dynamic Form Mapping Configuration
Manage MCA form field mappings dynamically without code changes.
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET |
/api/v1/mca/form-mappings |
🔒 | List all form mappings |
GET |
/api/v1/mca/form-mappings/:formType |
🔒 | Get specific form mapping |
POST |
/api/v1/mca/form-mappings |
🔒🔑 | Create form mapping (admin only) |
PUT |
/api/v1/mca/form-mappings/:formType |
🔒🔑 | Update form mapping (admin only) |
POST |
/api/v1/mca/form-mappings/:formType/toggle-active |
🔒🔑 | Toggle mapping active status |
Headers Required:
Authorization: Bearer <JWT>x-tenant-id: <tenant-uuid>x-admin: true(for admin-only endpoints)
GET /api/v1/mca/form-mappings
Query Parameters:
tenantId(optional): Filter by tenantactive(optional): Filter by active status (true/false)
Response:
{
"data": [
{
"id": "uuid",
"formType": "AOC-4",
"formVersion": "1.0",
"mcaUrl": "https://www.mca.gov.in/mcafoportal/aoc4Form.do",
"fieldMappings": [...],
"isActive": true,
"version": 1
}
]
}
POST /api/v1/mca/form-mappings
Request:
{
"formType": "AOC-4",
"formVersion": "1.0",
"mcaUrl": "https://www.mca.gov.in/mcafoportal/aoc4Form.do",
"fieldMappings": [
{
"profilePath": "cin",
"selectors": ["#txtCIN", "input[name='companyCIN']"],
"required": true
},
{
"profilePath": "dateOfIncorporation",
"selectors": ["#txtDateOfIncorporation"],
"transform": {
"type": "date",
"format": "DD/MM/YYYY"
}
}
],
"validationRules": {
"cin": {
"pattern": "^[UL][0-9]{5}[A-Z]{2}[0-9]{4}[A-Z]{3}[0-9]{6}$"
}
},
"metadata": {
"description": "Annual Financial Statements Filing",
"requiredDocuments": ["FINANCIAL_STATEMENT", "AUDITOR_REPORT"]
}
}
PUT /api/v1/mca/form-mappings/:formType
Request (includes version for optimistic locking):
{
"version": 1,
"fieldMappings": [...],
"isActive": true
}
Response (on conflict):
{
"error": "version_conflict",
"message": "Form mapping was modified by another user",
"currentVersion": 2,
"currentData": {...}
}
10.2 Entity Profile Management
Enhanced entity profile operations with optimistic locking.
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET |
/api/v1/entities/:id |
🔒 | Get entity profile with version |
PATCH |
/api/v1/entities/:id |
🔒 | Update entity profile |
GET /api/v1/entities/:id
Response:
{
"data": {
"id": "uuid",
"name": "Acme Corp",
"profileData": {
"cin": "U12345MH2023PTC987654",
"pan": "ABCDE1234F",
"_verification": {
"cin": {
"status": "verified",
"verifiedBy": "user-uuid",
"verifiedAt": "2024-03-01T10:30:00.000Z"
}
}
},
"version": 5
},
"version": 5
}
PATCH /api/v1/entities/:id
Request (version required for optimistic locking):
{
"version": 5,
"profileData": {
"cin": "U12345MH2023PTC987654",
"companyName": "Acme Private Limited"
}
}
Response (on success):
{
"message": "Entity updated successfully",
"data": {...},
"version": 6
}
Response (on conflict - HTTP 409):
{
"error": "Version conflict detected. The entity was modified by another user.",
"code": "VERSION_CONFLICT",
"currentVersion": 7,
"currentData": {...}
}
10.3 Document Upload and IDP Extraction
Upload documents and extract structured data using AI.
| Method | Endpoint | Auth | Description |
|---|---|---|---|
POST |
/api/v1/documents/upload |
🔒 | Upload document with extraction |
GET |
/api/v1/documents/:documentId |
🔒 | Get document (signed URL) |
GET |
/api/v1/entities/:entityId/documents |
🔒 | List entity documents |
GET |
/api/v1/idp/extract/:jobId |
🔒 | Get extraction job status |
POST /api/v1/documents/upload
Request (multipart/form-data):
file: Document file (PDF, JPG, PNG, TIFF, max 10MB)entityId: Entity UUIDdocumentType: PAN_CARD | GST_CERTIFICATE | CERTIFICATE_OF_INCORPORATION | FINANCIAL_STATEMENTtriggerExtraction: true/false (optional, default: true)
Response:
{
"documentId": "uuid",
"jobId": "uuid",
"status": "processing",
"message": "Document uploaded and extraction started"
}
GET /api/v1/idp/extract/:jobId
Response:
{
"jobId": "uuid",
"status": "completed",
"extractedData": {
"panNumber": "ABCDE1234F",
"name": "John Doe",
"dateOfBirth": "01/01/1990"
},
"confidence": {
"panNumber": 0.95,
"name": 0.88,
"dateOfBirth": 0.92
},
"verificationFlags": {
"name": "mandatory_verification"
},
"processingTime": 3500
}
10.4 Workflow-to-MCA Integration
Check workflow completion and redirect to MCA portal.
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET |
/api/v1/mca/workflow-redirect/:workflowId |
🔒 | Get MCA redirect information |
GET /api/v1/mca/workflow-redirect/:workflowId
Response (profile complete):
{
"ready": true,
"formType": "AOC-4",
"mcaUrl": "https://www.mca.gov.in/mcafoportal/aoc4Form.do",
"contextId": "uuid",
"message": "Entity profile is complete. You can proceed to MCA portal."
}
Response (profile incomplete):
{
"ready": false,
"formType": "AOC-4",
"missingFields": ["financialYear", "totalRevenue", "netProfit"],
"requiredDocuments": ["FINANCIAL_STATEMENT", "AUDITOR_REPORT"],
"message": "Entity profile is incomplete. Please complete the required fields and upload required documents."
}
10.5 Audit Trail Retrieval
Query audit logs for compliance and debugging.
| Method | Endpoint | Auth | Description |
|---|---|---|---|
GET |
/api/v1/audit/entity/:entityId |
🔒🔑 | Get entity audit trail |
GET |
/api/v1/audit/document/:documentId |
🔒🔑 | Get document audit trail |
GET |
/api/v1/audit/query |
🔒🔑 | Generic audit log query |
Headers Required:
Authorization: Bearer <JWT>x-tenant-id: <tenant-uuid>x-audit-access: true(orx-admin: true)
GET /api/v1/audit/entity/:entityId
Query Parameters:
startDate(optional): ISO date stringendDate(optional): ISO date stringaction(optional): Filter by action typeuserId(optional): Filter by userlimit(optional): Default 100offset(optional): Default 0
Response:
{
"data": [
{
"id": "uuid",
"action": "ENTITY_PROFILE_UPDATED",
"userId": "uuid",
"userName": "John Doe",
"timestamp": "2024-03-01T10:30:00.000Z",
"details": {...},
"changes": [
{
"field": "profileData",
"oldValue": {...},
"newValue": {...}
}
]
}
],
"pagination": {
"total": 150,
"limit": 100,
"offset": 0,
"hasMore": true
}
}
11. Real-time Events (QStash)
The Workflow Service publishes events via QStash for asynchronous delivery and real-time synchronization (SSE).
Event Exchange
- Name:
dotcos.events - Type:
topic - Durable:
true
Event Types
Profile Update Event
Routing Key: profile.updated.{entityId}
Payload:
{
"eventType": "profile.updated",
"entityId": "uuid",
"tenantId": "uuid",
"userId": "uuid",
"timestamp": "2024-03-01T10:30:00.000Z",
"changes": [
{
"field": "profileData",
"oldValue": {...},
"newValue": {...}
}
],
"version": 5
}
Extraction Completed Event
Routing Key: extraction.completed.{jobId}
Payload:
{
"eventType": "extraction.completed",
"jobId": "uuid",
"entityId": "uuid",
"tenantId": "uuid",
"documentType": "PAN_CARD",
"timestamp": "2024-03-01T10:30:00.000Z",
"extractedData": {
"panNumber": "ABCDE1234F",
"name": "John Doe"
}
}
Extraction Failed Event
Routing Key: extraction.failed.{jobId}
Payload:
{
"eventType": "extraction.failed",
"jobId": "uuid",
"entityId": "uuid",
"tenantId": "uuid",
"documentType": "PAN_CARD",
"timestamp": "2024-03-01T10:30:00.000Z",
"error": "Document text too short or unreadable"
}
Recommended Queue Bindings
- Frontend Profile Updates: Bind to
profile.updated.* - Extension Profile Updates: Bind to
profile.updated.* - Audit All Events: Bind to
#(all events)
See QStash integration for setup details.
Error Response Format
All API errors follow this structure:
{
"error": "Error message",
"code": "ERROR_CODE",
"correlationId": "uuid",
"details": {...}
}
Common Error Codes
MISSING_VERSION: Version number required for optimistic lockingVERSION_CONFLICT: Entity was modified by another userVALIDATION_ERROR: Request validation failedNOT_FOUND: Resource not foundUNAUTHORIZED: Authentication requiredFORBIDDEN: Insufficient permissions
HTTP Status Codes
200: Success201: Created400: Bad Request (validation error)401: Unauthorized (missing/invalid auth token)403: Forbidden (insufficient permissions)404: Not Found409: Conflict (version mismatch, duplicate resource)429: Too Many Requests (rate limit exceeded)500: Internal Server Error
Rate Limiting
IDP endpoints are rate-limited to 100 requests per minute per user.
Response (when limit exceeded):
{
"error": "Too many requests",
"retryAfter": 60
}
Headers:
X-RateLimit-Limit: 100X-RateLimit-Remaining: 0X-RateLimit-Reset: Unix timestampRetry-After: Seconds until reset