PolyAPI JSON Contract Specification¶
Overview¶
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.
Request Envelope¶
The request envelope is the format clients use to communicate with modules through the gateway.
Schema¶
{
"request_id": "uuid-v4-string",
"module": "sort",
"version": "1.0.0",
"payload": { }
}
Field Definitions¶
| 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 |
Validation Rules¶
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.
Response Envelope¶
All responses, whether success or error, must use the response envelope format.
Success Response Schema¶
{
"request_id": "uuid-v4-string",
"module": "sort",
"version": "1.0.0",
"status": "success",
"data": { },
"error": null
}
Error Response Schema¶
{
"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 Definitions¶
| 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 |
Error Object¶
| 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 |
Error Code Registry¶
| 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 |
Versioning Policy¶
Semantic Versioning¶
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
Contract Evolution¶
- 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
Module Version Support¶
- 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
Example Request/Response Pairs¶
Sort Module: String Sorting¶
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
}
Sort Module: Number Sorting (Descending)¶
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
}
Error: Empty Input¶
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
}
}
Error: Mixed Types¶
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
}
}
Health Check Response¶
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 |