This document defines the JSON contract standard for all inter-module communication in PolyAPI. Every module, regardless of the programming language, must communicate with the FastAPI gateway exclusively through HTTP + JSON following this contract.
The request envelope is the format clients use to communicate with modules through the gateway.
{
"request_id": "uuid-v4-string",
"module": "sort",
"version": "1.0.0",
"payload": { }
}| Field | Type | Required | Description |
|---|---|---|---|
request_id |
string | No | UUID v4 string. Auto-generated by gateway if not provided |
module |
string | Yes | Module identifier (e.g., "sort", "filter", "transform") |
version |
string | Yes | Module version in semver format (e.g., "1.0.0") |
payload |
object | Yes | Module-specific payload data |
request_id: Must be a valid UUID v4 if provided. If empty, gateway will inject one.module: Must be a non-empty string matching a registered module.version: Must follow semver format (MAJOR.MINOR.PATCH).payload: Must be a valid JSON object. Content validation is module-specific.
All responses, whether success or error, must use the response envelope format.
{
"request_id": "uuid-v4-string",
"module": "sort",
"version": "1.0.0",
"status": "success",
"data": { },
"error": null
}{
"request_id": "uuid-v4-string",
"module": "sort",
"version": "1.0.0",
"status": "error",
"data": null,
"error": {
"code": "INVALID_INPUT",
"message": "Human-readable explanation",
"details": { }
}
}| Field | Type | Required | Description |
|---|---|---|---|
request_id |
string | Yes | Matches the request_id from the incoming request |
module |
string | Yes | Module identifier |
version |
string | Yes | Module version |
status |
string | Yes | Either "success" or "error" |
data |
object/null | Yes | Response data on success, null on error |
error |
object/null | Yes | Error details on error, null on success |
| Field | Type | Required | Description |
|---|---|---|---|
code |
string | Yes | Error code from the registry |
message |
string | Yes | Human-readable error message |
details |
object/null | No | Additional error context |
| Code | Description | HTTP Status |
|---|---|---|
INVALID_INPUT |
Request payload failed validation | 400 |
EMPTY_INPUT |
Required input array is empty | 400 |
MIXED_TYPES |
Array contains mixed data types | 400 |
INVALID_ORDER |
Invalid sort order value | 400 |
UNSUPPORTED_TYPE |
Unsupported data type in array | 400 |
MODULE_UNREACHABLE |
Module is not responding | 502 |
CONTRACT_VIOLATION |
Response doesn't match contract | 500 |
INVALID_JSON |
Malformed JSON in request | 400 |
INVALID_METHOD |
Wrong HTTP method used | 405 |
MODULE_ERROR |
Module returned an error | 502 |
PolyAPI follows Semantic Versioning 2.0.0:
- MAJOR (x.0.0): Breaking changes
- MINOR (1.x.0): New features (backward compatible)
- PATCH (1.0.x): Bug fixes
-
Backward-Compatible Changes (Minor version bump):
- Adding new optional fields
- Adding new error codes
- Adding new modules
-
Breaking Changes (Major version bump):
- Removing or renaming required fields
- Changing field types
- Changing enum values
- Removing error codes
- Gateway should support multiple versions of a module simultaneously
- Modules should maintain backward compatibility within major version
- Deprecation notices should be issued one minor version in advance
Request:
{
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"module": "sort",
"version": "1.0.0",
"payload": {
"items": ["banana", "apple", "cherry"],
"order": "asc"
}
}Response:
{
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"module": "sort",
"version": "1.0.0",
"status": "success",
"data": {
"sorted": ["apple", "banana", "cherry"],
"item_type": "string",
"count": 3
},
"error": null
}Request:
{
"request_id": "550e8400-e29b-41d4-a716-446655440001",
"module": "sort",
"version": "1.0.0",
"payload": {
"items": [5, 2, 8, 1],
"order": "desc"
}
}Response:
{
"request_id": "550e8400-e29b-41d4-a716-446655440001",
"module": "sort",
"version": "1.0.0",
"status": "success",
"data": {
"sorted": [8, 5, 2, 1],
"item_type": "number",
"count": 4
},
"error": null
}Request:
{
"request_id": "550e8400-e29b-41d4-a716-446655440002",
"module": "sort",
"version": "1.0.0",
"payload": {
"items": [],
"order": "asc"
}
}Response:
{
"request_id": "550e8400-e29b-41d4-a716-446655440002",
"module": "sort",
"version": "1.0.0",
"status": "error",
"data": null,
"error": {
"code": "EMPTY_INPUT",
"message": "input array is empty",
"details": null
}
}Request:
{
"request_id": "550e8400-e29b-41d4-a716-446655440003",
"module": "sort",
"version": "1.0.0",
"payload": {
"items": ["string", 123, "another"],
"order": "asc"
}
}Response:
{
"request_id": "550e8400-e29b-41d4-a716-446655440003",
"module": "sort",
"version": "1.0.0",
"status": "error",
"data": null,
"error": {
"code": "MIXED_TYPES",
"message": "mixed types in array",
"details": null
}
}Modules must implement a health check endpoint that returns:
{
"status": "ok",
"module": "sort",
"version": "1.0.0"
}| Field | Type | Description |
|---|---|---|
status |
string | "ok" when healthy |
module |
string | Module name |
version |
string | Module version |