{
    "openapi": "3.1.0",
    "info": {
        "title": "AIRLERT-OPEN-API",
        "version": "1.0.0",
        "description": "Outbound partner cloud delivery for selected AIRLERT HUB ingested messages."
    },
    "servers": [
        {
            "url": "http://mirror.airlert.co.uk/php"
        }
    ],
    "paths": {
        "/airlert_open_api_spec.php": {
            "get": {
                "summary": "Download the AIRLERT-OPEN-API OpenAPI document",
                "operationId": "getAirlertOpenApiSpec",
                "responses": {
                    "200": {
                        "description": "OpenAPI JSON document",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/airlert_open_api_sandbox_receiver.php": {
            "post": {
                "summary": "Sandbox receiver for AIRLERT-OPEN-API test deliveries",
                "description": "Local portal endpoint used by administrators to validate payload shape, security headers, and timing before using an external partner endpoint.",
                "operationId": "postAirlertOpenApiSandboxReceiver",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/HubMessageIngestedEvent"
                            }
                        }
                    }
                },
                "responses": {
                    "202": {
                        "description": "Accepted by sandbox receiver"
                    },
                    "400": {
                        "description": "Invalid JSON payload"
                    },
                    "405": {
                        "description": "Method not allowed"
                    }
                }
            }
        }
    },
    "webhooks": {
        "hubMessageIngested": {
            "post": {
                "summary": "Partner cloud endpoint receiving selected HUB messages",
                "description": "AIRLERT posts this payload to each configured partner endpoint after a selected HUB message is stored.",
                "operationId": "receiveAirlertHubMessage",
                "security": [
                    {
                        "bearerAuth": []
                    },
                    {
                        "airlertSignature": []
                    }
                ],
                "parameters": [
                    {
                        "name": "X-Airlert-Event",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "const": "hub.message.ingested"
                        }
                    },
                    {
                        "name": "X-Airlert-Delivery-Id",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "X-Airlert-Signature",
                        "in": "header",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "example": "sha256=..."
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/HubMessageIngestedEvent"
                            },
                            "examples": {
                                "bedExit": {
                                    "summary": "Example HUB message",
                                    "value": {
                                        "type": "airlert.hub.message.ingested",
                                        "schema_version": "1.0",
                                        "event_id": "airlert-9a8b7c6d5e4f3210abcd1234-a1b2c3d4",
                                        "occurred_at_unix": 1781766000,
                                        "occurred_at": "2026-06-18T06:20:00Z",
                                        "source": "airlert_portal",
                                        "ingest_endpoint": "tttupload.php",
                                        "hub": {
                                            "canonical_hub_id": 42,
                                            "user_data_hub_id": 42,
                                            "hub_name": "Bedroom hub",
                                            "user_id": 3
                                        },
                                        "message": {
                                            "location": "Room 1",
                                            "sensor": "Bed pad",
                                            "raw": "Not Return to Bed",
                                            "presented": "Not Return to Bed",
                                            "user_data_id": 123456
                                        }
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Accepted"
                    },
                    "202": {
                        "description": "Accepted for asynchronous processing"
                    },
                    "400": {
                        "description": "Invalid payload"
                    },
                    "401": {
                        "description": "Invalid bearer token or signature"
                    },
                    "429": {
                        "description": "Rate limited"
                    },
                    "500": {
                        "description": "Partner platform error"
                    }
                }
            }
        }
    },
    "components": {
        "securitySchemes": {
            "bearerAuth": {
                "type": "http",
                "scheme": "bearer",
                "bearerFormat": "Opaque token"
            },
            "airlertSignature": {
                "type": "apiKey",
                "in": "header",
                "name": "X-Airlert-Signature",
                "description": "HMAC-SHA256 of the raw JSON body using the configured shared_secret, formatted as sha256=<hex>."
            }
        },
        "schemas": {
            "HubMessageIngestedEvent": {
                "type": "object",
                "required": [
                    "type",
                    "schema_version",
                    "event_id",
                    "occurred_at_unix",
                    "occurred_at",
                    "source",
                    "ingest_endpoint",
                    "hub",
                    "message"
                ],
                "properties": {
                    "type": {
                        "type": "string",
                        "const": "airlert.hub.message.ingested"
                    },
                    "schema_version": {
                        "type": "string",
                        "example": "1.0"
                    },
                    "event_id": {
                        "type": "string"
                    },
                    "occurred_at_unix": {
                        "type": "integer"
                    },
                    "occurred_at": {
                        "type": "string",
                        "format": "date-time"
                    },
                    "source": {
                        "type": "string",
                        "const": "airlert_portal"
                    },
                    "ingest_endpoint": {
                        "type": "string"
                    },
                    "hub": {
                        "$ref": "#/components/schemas/HubSummary"
                    },
                    "message": {
                        "$ref": "#/components/schemas/HubMessage"
                    }
                },
                "additionalProperties": false
            },
            "HubSummary": {
                "type": "object",
                "required": [
                    "canonical_hub_id",
                    "user_data_hub_id",
                    "hub_name",
                    "user_id"
                ],
                "properties": {
                    "canonical_hub_id": {
                        "type": "integer"
                    },
                    "user_data_hub_id": {
                        "type": "integer"
                    },
                    "hub_name": {
                        "type": "string"
                    },
                    "user_id": {
                        "type": "integer"
                    }
                },
                "additionalProperties": false
            },
            "HubMessage": {
                "type": "object",
                "required": [
                    "location",
                    "sensor",
                    "raw",
                    "presented",
                    "user_data_id"
                ],
                "properties": {
                    "location": {
                        "type": "string"
                    },
                    "sensor": {
                        "type": "string"
                    },
                    "raw": {
                        "type": "string"
                    },
                    "presented": {
                        "type": "string"
                    },
                    "user_data_id": {
                        "type": "integer"
                    }
                },
                "additionalProperties": false
            }
        }
    }
}