API Overview
Introduction
The ESG Data Collection Platform provides a RESTful API for mobile collectors, web frontends, and admin dashboards to submit, review, and report on ESG (Environmental, Social, and Governance) metrics.
The API supports: - Data Collection: Mobile and web submission of environmental, social, and governance metrics - Review & Approval: Workflow management for data validation and approval - Report Generation: Automated generation of GRI sustainability reports, carbon footprint reports, human capital reports (GRI 405-1, GRI 401), and environment reports (G.1-G.10) - Administration: User management, metric catalog configuration, and audit logging
This document outlines the fundamental API conventions, authentication mechanisms, versioning strategy, and rate limiting rules that apply across all endpoints.
Base URL
Production: https://api.esgplatform.com
Staging: https://staging-api.esgplatform.com
Development: http://localhost:8080
All API endpoints are prefixed with /api/v1/ unless otherwise specified.
Authentication
JWT Authentication
The API uses JSON Web Tokens (JWT) for authentication. All endpoints except /api/v1/auth/login and /api/v1/auth/refresh require a valid JWT token.
Token Structure
{
"header": {
"alg": "HS256",
"typ": "JWT"
},
"payload": {
"sub": "user-uuid",
"tenant_id": "tenant-uuid",
"roles": ["COLLECTOR", "REVIEWER"],
"iat": 1704067200,
"exp": 1704153600
}
}
Authentication Flow
- Login: Obtain access and refresh tokens
POST /api/v1/auth/login
Content-Type: application/json
{
"email": "user@example.com",
"password": "securePassword123"
}
Response:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 86400,
"user": {
"id": "user-uuid",
"email": "user@example.com",
"roles": ["COLLECTOR"]
}
}
- Authenticated Requests: Include token in Authorization header
- Token Refresh: Obtain new access token before expiration
POST /api/v1/auth/refresh
Content-Type: application/json
{
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Response:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 86400
}
Token Lifecycle
- Access Token: Valid for 24 hours
- Refresh Token: Valid for 30 days
- Session Storage: Redis-backed for revocation capability
- Logout: Invalidates both tokens immediately
Password Security
- Hashing: Quarkus Elytron password providers (BCrypt, PBKDF2, scrypt)
- Failed Login: Account lockout after 5 failed attempts (15-minute lockout)
- Password Requirements: Minimum 12 characters, must include uppercase, lowercase, number, and special character
Tenant Isolation
All authenticated requests automatically scope data access to the user's tenant. The tenant_id from the JWT is enforced at the database query level to ensure complete data isolation between organizations.
Attempting to access resources from another tenant results in:
{
"error": "RESOURCE_NOT_FOUND",
"message": "The requested resource does not exist",
"timestamp": "2025-01-11T10:30:00Z",
"request_id": "req_abc123"
}
API Versioning
Versioning Strategy
The API uses URI versioning with the version identifier in the path: /api/v1/, /api/v2/, etc.
Version Support Policy
- Current Version: v1
- Support Window: Each major version is supported for 24 months after the next version's release
- Deprecation Notice: 6 months advance notice via email, API headers, and documentation
- Breaking Changes: Only introduced in new major versions
Version Headers
All responses include version information:
When an endpoint is deprecated:
HTTP/1.1 200 OK
X-API-Version: v1
X-API-Deprecated: true
X-API-Deprecation-Date: 2026-06-01
X-API-Sunset-Date: 2026-12-01
Link: </api/v2/collector/submissions>; rel="successor-version"
Breaking vs Non-Breaking Changes
Non-Breaking Changes (patch/minor versions): - Adding new endpoints - Adding optional request parameters - Adding new fields to responses - Adding new response codes for edge cases - Relaxing validation rules
Breaking Changes (major versions only): - Removing endpoints - Removing request/response fields - Changing field types - Making optional fields required - Changing authentication mechanisms - Changing error response structure
Version Migration
When migrating to a new version:
1. Review the migration guide at /docs/api/migration-v1-to-v2.md
2. Test thoroughly in staging environment
3. Update client code to use new version path
4. Monitor for deprecation headers
5. Complete migration before sunset date
Rate Limiting
Rate Limit Rules
Rate limits protect the API from abuse and ensure fair resource allocation across all users.
Limits by Endpoint Category
| Endpoint Category | Rate Limit | Window | Scope |
|---|---|---|---|
Authentication (/auth/*) |
10 requests | 15 minutes | IP address |
Collector API (/collector/*) |
1000 requests | 1 hour | User + Tenant |
Admin API (/admin/*) |
500 requests | 1 hour | User + Tenant |
| Report Generation | 10 reports | 1 hour | Tenant |
| File Upload | 100 uploads | 1 hour | User + Tenant |
| Sync Endpoint | 60 requests | 1 minute | User |
Rate Limit Headers
All responses include rate limit information:
HTTP/1.1 200 OK
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 987
X-RateLimit-Reset: 1704153600
X-RateLimit-Window: 3600
Where:
- X-RateLimit-Limit: Maximum requests allowed in the window
- X-RateLimit-Remaining: Requests remaining in current window
- X-RateLimit-Reset: Unix timestamp when the window resets
- X-RateLimit-Window: Window size in seconds
Rate Limit Exceeded Response
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 3600
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1704153600
{
"error": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Please retry after 3600 seconds.",
"limit": 1000,
"window": 3600,
"retry_after": 3600,
"timestamp": "2025-01-11T10:30:00Z",
"request_id": "req_abc123"
}
Rate Limit Best Practices
- Monitor Headers: Check
X-RateLimit-Remainingbefore making bulk requests - Implement Backoff: Use exponential backoff when receiving 429 responses
- Batch Operations: Use batch endpoints when available (e.g., bulk submission creation)
- Cache Responses: Cache GET responses to reduce redundant requests
- Contact Support: Request limit increases for legitimate high-volume use cases
Enterprise Rate Limits
Enterprise customers can request higher rate limits by contacting support. Custom limits are configured per tenant based on usage patterns and SLA agreements.
API Conventions
HTTP Methods
The API follows RESTful conventions for HTTP methods:
| Method | Usage | Idempotent |
|---|---|---|
| GET | Retrieve resources | Yes |
| POST | Create resources, trigger actions | No* |
| PUT | Replace entire resource | Yes |
| PATCH | Partial update | No |
| DELETE | Remove resource (soft delete) | Yes |
*POST endpoints with idempotency keys are idempotent
Idempotency
All POST endpoints that create resources support idempotency to prevent duplicate submissions from network retries.
Idempotency Key
Include an Idempotency-Key header with a unique identifier (e.g., UUID v4):
POST /api/v1/collector/submissions
Authorization: Bearer token...
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
Content-Type: application/json
{
"metric_template_id": "metric-uuid",
"value": 42.5,
...
}
Behavior: - First request with a new key: Creates the resource, returns 201 Created - Duplicate request with same key within 24 hours: Returns original 201 response from cache - After 24 hours: Key expires, treated as new request
Request Format
Content Type
All request bodies must use application/json unless uploading files (which use multipart/form-data).
Request Body Structure
Request bodies use camelCase for field names:
{
"metricTemplateId": "uuid",
"value": 42.5,
"collectedAt": "2025-01-11T10:30:00Z",
"metadata": {
"source": "manual",
"notes": "Measured during morning shift"
}
}
Date/Time Format
All dates and timestamps use ISO 8601 format with UTC timezone:
Response Format
Content Type
All responses return application/json:
Success Response Structure
Success responses use camelCase and include relevant metadata:
{
"id": "uuid",
"metricTemplateId": "uuid",
"value": 42.5,
"state": "VALIDATED",
"createdAt": "2025-01-11T10:30:00Z",
"updatedAt": "2025-01-11T10:35:00Z"
}
Collection Response Structure
Collection endpoints return paginated results:
{
"data": [
{ "id": "uuid1", ... },
{ "id": "uuid2", ... }
],
"pagination": {
"page": 1,
"pageSize": 50,
"totalPages": 10,
"totalItems": 487,
"hasNext": true,
"hasPrevious": false
},
"links": {
"self": "/api/v1/collector/submissions?page=1&pageSize=50",
"next": "/api/v1/collector/submissions?page=2&pageSize=50",
"last": "/api/v1/collector/submissions?page=10&pageSize=50"
}
}
Error Response Structure
All errors follow a consistent format (see Error Handling for details):
{
"error": "VALIDATION_ERROR",
"message": "Invalid submission data",
"timestamp": "2025-01-11T10:30:00Z",
"request_id": "req_abc123",
"details": [
{
"field": "value",
"code": "VALUE_OUT_OF_RANGE",
"message": "Value must be between 0 and 1000"
}
]
}
HTTP Status Codes
The API uses standard HTTP status codes:
Success Codes (2xx)
200 OK: Request succeeded201 Created: Resource created successfully202 Accepted: Request accepted for async processing204 No Content: Success with no response body (e.g., DELETE)
Client Error Codes (4xx)
400 Bad Request: Invalid request format or validation error401 Unauthorized: Missing or invalid authentication token403 Forbidden: Authenticated but lacking permissions404 Not Found: Resource does not exist409 Conflict: Resource conflict (e.g., duplicate submission)422 Unprocessable Entity: Valid format but business rule violation429 Too Many Requests: Rate limit exceeded
Server Error Codes (5xx)
500 Internal Server Error: Unexpected server error502 Bad Gateway: Upstream service failure503 Service Unavailable: Service temporarily unavailable504 Gateway Timeout: Upstream service timeout
Pagination
All collection endpoints support pagination with consistent query parameters:
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page |
integer | 1 | Page number (1-indexed) |
pageSize |
integer | 50 | Items per page (max 100) |
sort |
string | - | Sort field and direction (e.g., createdAt:desc) |
Response Format
See Collection Response Structure above.
Filtering and Searching
Collection endpoints support filtering via query parameters:
Common filter parameters:
- state: Filter by submission state
- periodId: Filter by reporting period
- search: Full-text search across relevant fields
- createdAfter / createdBefore: Filter by creation date
- metricTemplateId: Filter by metric template
Request ID Tracking
Every request includes a unique request ID for tracing:
This ID appears in: - Response headers - Error messages - Application logs - Support tickets
When reporting issues, always include the request ID.
CORS Configuration
The API supports Cross-Origin Resource Sharing (CORS) for web frontends:
Allowed Origins:
- https://app.esgplatform.com (production)
- https://staging.esgplatform.com (staging)
- http://localhost:3000 (development)
Allowed Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
Allowed Headers: Authorization, Content-Type, Idempotency-Key, X-Request-ID
Exposed Headers: X-RateLimit-*, X-API-Version, X-Request-ID
Credentials: Supported (cookies and authentication headers)
Compression
The API supports gzip compression. Include the Accept-Encoding header:
Response:
Security Considerations
HTTPS Only
All production and staging endpoints require HTTPS. HTTP requests are automatically redirected to HTTPS.
API Keys vs JWT
- JWT Tokens: Used for user authentication (web/mobile apps)
- API Keys: Not currently supported (may be added for machine-to-machine integrations)
Security Headers
All responses include security headers:
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Content-Security-Policy: default-src 'self'
Input Validation
All inputs are validated before processing: - Request body structure validation - Field type validation - Business rule validation - SQL injection prevention - XSS prevention
Sensitive Data
The following fields are considered sensitive and are: - Encrypted at rest in the database - Redacted in logs - Excluded from error messages
Sensitive fields: password, jwt_secret, PII fields (name, email when required by GDPR)
API Documentation
Interactive Documentation
Explore the API interactively using Quarkus Swagger UI (SmallRye OpenAPI):
OpenAPI Specification
Download the OpenAPI 3.0 specification:
Additional Documentation
- Collector API Reference
- Admin API Reference
- Stakeholder Engagement API
- Community Investment API
- Error Handling
- Webhooks
- Report Outputs - Report types including Human Capital (E.1-E.3) and Environment (G.1-G.10)
Support
For API questions or issues: - Documentation: https://docs.esgplatform.com - Email: api-support@esgplatform.com - Status Page: https://status.esgplatform.com
Changelog
v1.0.0 (2025-01-11)
- Initial API release
- JWT authentication
- Collector and Admin endpoints
- Rate limiting
- Comprehensive error handling
v1.1.0 (2026-01-17)
- Added human capital report generation endpoints
- Support for GRI 405-1 and GRI 401 reporting
- CSV/XLSX export formats for HR metrics
- Advanced filtering and aggregation options