REST API Structure & Conventions
Zynka ONE's REST API follows RESTful principles with OCPI-specific conventions. All endpoints use JSON for request/response bodies and standard HTTP status codes.
Base URL
https://api.zynka.one/ocpi/{version}/{module}/{endpoint}
Path Parameters:
version: OCPI version (e.g.,2.2.1)module: API module (cpofor CPO endpoints,emspfor eMSP endpoints)endpoint: Specific resource endpoint
Authentication
All API requests require authentication using OCPI tokens in the Authorization header.
curl -H "Authorization: Token YOUR_OCPI_TOKEN" \
https://api.zynka.one/ocpi/2.2.1/cpo/locations
Never expose OCPI tokens in client-side code or public repositories.
HTTP Methods
| Method | Usage | Example |
|---|---|---|
GET | Retrieve resources | Get location details |
POST | Create new resources | Start charging session |
PUT | Update/replace resources | Update location info |
PATCH | Partial updates | Update EVSE status |
DELETE | Remove resources | Remove location |
Request/Response Format
Request Headers
Content-Type: application/json
Authorization: Token YOUR_OCPI_TOKEN
X-Request-ID: unique-request-id (optional)
X-Correlation-ID: correlation-id (optional)
Response Headers
Content-Type: application/json
X-Request-ID: echoed-request-id
X-Correlation-ID: echoed-correlation-id
X-Total-Count: 150 (for paginated responses)
Link: <https://api.zynka.one/...>; rel="next" (pagination)
Success Response
{
"status_code": 1000,
"status_message": "Success",
"data": {
// Response data
},
"timestamp": "2024-01-15T10:30:00Z"
}
Error Response
{
"status_code": 2000,
"status_message": "Generic client error",
"error": {
"code": "INVALID_REQUEST",
"description": "The request was malformed",
"details": {
"field": "party_id",
"issue": "Must be 3 characters"
}
},
"timestamp": "2024-01-15T10:30:00Z"
}
Status Codes
Success Codes (1000-1999)
1000: Generic success1001: Created successfully1002: Updated successfully1003: Deleted successfully
Client Error Codes (2000-2999)
2000: Generic client error2001: Invalid request format2002: Authentication failed2003: Authorization failed2004: Not found2005: Method not allowed2006: Conflict2007: Rate limit exceeded
Server Error Codes (3000-3999)
3000: Generic server error3001: Temporary unavailable3002: Database error3003: External service error
Pagination
Large result sets are paginated with a default limit of 50 items.
GET /ocpi/2.2.1/cpo/locations?limit=20&offset=40
Query Parameters:
limit: Maximum items per page (1-100)offset: Number of items to skipdate_from: Filter by last_updated (ISO 8601)date_to: Filter by last_updated (ISO 8601)
Response Headers:
X-Total-Count: 150
Link: <https://api.zynka.one/ocpi/2.2.1/cpo/locations?limit=20&offset=60>; rel="next"
Rate Limiting
API requests are rate limited to prevent abuse.
Limits:
- 1000 requests per hour per token
- 100 requests per minute per token
- Burst limit: 20 requests per second
Rate Limit Headers:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 950
X-RateLimit-Reset: 1640995200
Retry-After: 60 (when limit exceeded)
Rate limits reset at the start of each hour/minute window.
Versioning
API versioning follows OCPI specification:
- 2.2.1: Current production version (recommended)
- 2.1.1: Legacy support (deprecated)
- 2.0: Legacy support (deprecated)
Specify version in URL path:
https://api.zynka.one/ocpi/2.2.1/cpo/locations
Content Types
JSON Schema Validation
All requests/responses follow OCPI JSON schemas. Invalid data returns 2001 status code.
Date/Time Format
All timestamps use ISO 8601 format with timezone:
{
"last_updated": "2024-01-15T10:30:00+05:30",
"created": "2024-01-15T10:30:00Z"
}
Currency Format
Monetary values use string representation to avoid floating-point precision issues:
{
"price": "12.50",
"currency": "INR"
}
Error Handling
Retry Logic
Implement exponential backoff for transient errors:
async function apiCallWithRetry(url, options, maxRetries = 3) {
let attempt = 0;
while (attempt < maxRetries) {
try {
const response = await fetch(url, options);
if (response.status === 429) {
// Rate limited
const retryAfter = response.headers.get('Retry-After');
await new Promise(resolve =>
setTimeout(resolve, (retryAfter || 60) * 1000)
);
attempt++;
continue;
}
if (response.status >= 500) {
// Server error, retry
const delay = Math.pow(2, attempt) * 1000; // Exponential backoff
await new Promise(resolve => setTimeout(resolve, delay));
attempt++;
continue;
}
return response;
} catch (error) {
if (attempt === maxRetries - 1) throw error;
const delay = Math.pow(2, attempt) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
attempt++;
}
}
}
Idempotency
Use X-Request-ID header for idempotent operations:
X-Request-ID: unique-request-uuid
Generate unique request IDs for all POST/PUT/PATCH operations to ensure idempotency.
Webhooks
Zynka ONE supports webhooks for real-time event notifications.
Configuration
POST /ocpi/2.2.1/webhooks
Content-Type: application/json
Authorization: Token YOUR_OCPI_TOKEN
{
"url": "https://your-app.com/webhooks/ocpi",
"events": ["session.started", "session.stopped", "location.updated"],
"secret": "webhook-secret-for-verification"
}
Event Payload
{
"event": "session.started",
"data": {
"session_id": "SESS001",
"location_id": "LOC001",
"evse_id": "EVSE001",
"timestamp": "2024-01-15T10:30:00Z"
},
"signature": "hmac-sha256-signature"
}
Testing
Sandbox Environment
Use sandbox for development and testing:
https://sandbox-api.zynka.one/ocpi/2.2.1/
Test Credentials
Contact support for sandbox credentials with unlimited rate limits.
Sandbox data is reset daily. Production credentials required for live integration.