{
  "openapi": "3.1.0",
  "info": {
    "title": "Aztraliz Messaging API",
    "version": "1.1.0",
    "description": "Server-to-server text and managed media messaging for external chat. Compatible /v1 endpoints. Files are scoped to one conversation and uploader. Never embed tokens in clients. 120 successful operations/minute per integration; uploads use two operations (authorization and persistence). Signed conversation.deleted webhooks synchronize administrator deletions with the connected app."
  },
  "servers": [
    {
      "url": "https://{host}/api/messaging/v1",
      "variables": {
        "host": {
          "default": "your-business.aztraliz.com",
          "description": "Use the host supplied by the administrator"
        }
      }
    }
  ],
  "tags": [
    {
      "name": "Messaging"
    }
  ],
  "paths": {
    "/me": {
      "get": {
        "operationId": "getIntegration",
        "summary": "Verify integration and scopes",
        "tags": [
          "Messaging"
        ],
        "security": [
          {
            "MessagingToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation or replay",
            "headers": {
              "X-Aztraliz-Request-Id": {
                "schema": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "X-Aztraliz-API-Version": {
                "schema": {
                  "type": "string",
                  "const": "1.1"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntegrationResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400"
          },
          "401": {
            "$ref": "#/components/responses/Error401"
          },
          "403": {
            "$ref": "#/components/responses/Error403"
          },
          "404": {
            "$ref": "#/components/responses/Error404"
          },
          "429": {
            "$ref": "#/components/responses/Error429"
          },
          "503": {
            "$ref": "#/components/responses/Error503"
          }
        }
      }
    },
    "/conversations": {
      "get": {
        "operationId": "listConversations",
        "summary": "List owned conversations",
        "tags": [
          "Messaging"
        ],
        "security": [
          {
            "MessagingToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation or replay",
            "headers": {
              "X-Aztraliz-Request-Id": {
                "schema": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "X-Aztraliz-API-Version": {
                "schema": {
                  "type": "string",
                  "const": "1.1"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConversationsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400"
          },
          "401": {
            "$ref": "#/components/responses/Error401"
          },
          "403": {
            "$ref": "#/components/responses/Error403"
          },
          "404": {
            "$ref": "#/components/responses/Error404"
          },
          "429": {
            "$ref": "#/components/responses/Error429"
          },
          "503": {
            "$ref": "#/components/responses/Error503"
          }
        },
        "x-required-scopes": [
          "conversations:read"
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "after",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Opaque cursor; nextCursor pages, lastCursor resumes later."
          }
        ]
      },
      "post": {
        "operationId": "upsertConversation",
        "summary": "Create or recover a conversation",
        "tags": [
          "Messaging"
        ],
        "security": [
          {
            "MessagingToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation or replay",
            "headers": {
              "X-Aztraliz-Request-Id": {
                "schema": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "X-Aztraliz-API-Version": {
                "schema": {
                  "type": "string",
                  "const": "1.1"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConversationResponse"
                }
              }
            }
          },
          "201": {
            "description": "Resource persisted",
            "headers": {
              "X-Aztraliz-Request-Id": {
                "schema": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "X-Aztraliz-API-Version": {
                "schema": {
                  "type": "string",
                  "const": "1.1"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConversationResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400"
          },
          "401": {
            "$ref": "#/components/responses/Error401"
          },
          "403": {
            "$ref": "#/components/responses/Error403"
          },
          "404": {
            "$ref": "#/components/responses/Error404"
          },
          "429": {
            "$ref": "#/components/responses/Error429"
          },
          "503": {
            "$ref": "#/components/responses/Error503"
          },
          "409": {
            "$ref": "#/components/responses/Error409"
          },
          "413": {
            "$ref": "#/components/responses/Error413"
          },
          "415": {
            "$ref": "#/components/responses/Error415"
          }
        },
        "x-required-scopes": [
          "conversations:write"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConversationInput"
              }
            }
          }
        }
      }
    },
    "/conversations/{conversationId}": {
      "get": {
        "operationId": "getConversation",
        "summary": "Read a conversation",
        "tags": [
          "Messaging"
        ],
        "security": [
          {
            "MessagingToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation or replay",
            "headers": {
              "X-Aztraliz-Request-Id": {
                "schema": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "X-Aztraliz-API-Version": {
                "schema": {
                  "type": "string",
                  "const": "1.1"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConversationResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400"
          },
          "401": {
            "$ref": "#/components/responses/Error401"
          },
          "403": {
            "$ref": "#/components/responses/Error403"
          },
          "404": {
            "$ref": "#/components/responses/Error404"
          },
          "429": {
            "$ref": "#/components/responses/Error429"
          },
          "503": {
            "$ref": "#/components/responses/Error503"
          }
        },
        "x-required-scopes": [
          "conversations:read"
        ],
        "parameters": [
          {
            "name": "conversationId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            },
            "description": "Opaque Aztraliz ID"
          }
        ]
      }
    },
    "/conversations/{conversationId}/messages": {
      "get": {
        "operationId": "listMessages",
        "summary": "Read chronological history",
        "tags": [
          "Messaging"
        ],
        "security": [
          {
            "MessagingToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation or replay",
            "headers": {
              "X-Aztraliz-Request-Id": {
                "schema": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "X-Aztraliz-API-Version": {
                "schema": {
                  "type": "string",
                  "const": "1.1"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessagesResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400"
          },
          "401": {
            "$ref": "#/components/responses/Error401"
          },
          "403": {
            "$ref": "#/components/responses/Error403"
          },
          "404": {
            "$ref": "#/components/responses/Error404"
          },
          "429": {
            "$ref": "#/components/responses/Error429"
          },
          "503": {
            "$ref": "#/components/responses/Error503"
          }
        },
        "x-required-scopes": [
          "messages:read"
        ],
        "parameters": [
          {
            "name": "conversationId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            },
            "description": "Opaque Aztraliz ID"
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "after",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Opaque cursor; nextCursor pages, lastCursor resumes later."
          }
        ]
      },
      "post": {
        "operationId": "receiveMessage",
        "summary": "Send a customer message to Aztraliz",
        "tags": [
          "Messaging"
        ],
        "security": [
          {
            "MessagingToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation or replay",
            "headers": {
              "X-Aztraliz-Request-Id": {
                "schema": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "X-Aztraliz-API-Version": {
                "schema": {
                  "type": "string",
                  "const": "1.1"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageResponse"
                }
              }
            }
          },
          "201": {
            "description": "Resource persisted",
            "headers": {
              "X-Aztraliz-Request-Id": {
                "schema": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "X-Aztraliz-API-Version": {
                "schema": {
                  "type": "string",
                  "const": "1.1"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400"
          },
          "401": {
            "$ref": "#/components/responses/Error401"
          },
          "403": {
            "$ref": "#/components/responses/Error403"
          },
          "404": {
            "$ref": "#/components/responses/Error404"
          },
          "429": {
            "$ref": "#/components/responses/Error429"
          },
          "503": {
            "$ref": "#/components/responses/Error503"
          },
          "409": {
            "$ref": "#/components/responses/Error409"
          },
          "413": {
            "$ref": "#/components/responses/Error413"
          },
          "415": {
            "$ref": "#/components/responses/Error415"
          }
        },
        "x-required-scopes": [
          "messages:write"
        ],
        "parameters": [
          {
            "name": "conversationId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            },
            "description": "Opaque Aztraliz ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MessageInput"
              }
            }
          }
        }
      }
    },
    "/conversations/{conversationId}/messages/{messageId}/receipt": {
      "post": {
        "operationId": "recordReceipt",
        "summary": "Confirm delivery or reading",
        "tags": [
          "Messaging"
        ],
        "security": [
          {
            "MessagingToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation or replay",
            "headers": {
              "X-Aztraliz-Request-Id": {
                "schema": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "X-Aztraliz-API-Version": {
                "schema": {
                  "type": "string",
                  "const": "1.1"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400"
          },
          "401": {
            "$ref": "#/components/responses/Error401"
          },
          "403": {
            "$ref": "#/components/responses/Error403"
          },
          "404": {
            "$ref": "#/components/responses/Error404"
          },
          "429": {
            "$ref": "#/components/responses/Error429"
          },
          "503": {
            "$ref": "#/components/responses/Error503"
          },
          "413": {
            "$ref": "#/components/responses/Error413"
          },
          "415": {
            "$ref": "#/components/responses/Error415"
          }
        },
        "x-required-scopes": [
          "receipts:write"
        ],
        "parameters": [
          {
            "name": "conversationId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            },
            "description": "Opaque Aztraliz ID"
          },
          {
            "name": "messageId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            },
            "description": "Opaque Aztraliz ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReceiptInput"
              }
            }
          }
        }
      }
    },
    "/conversations/{conversationId}/attachments": {
      "post": {
        "operationId": "uploadAttachment",
        "summary": "Upload one managed file (messages:write)",
        "tags": [
          "Messaging"
        ],
        "security": [
          {
            "MessagingToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Successful operation or replay",
            "headers": {
              "X-Aztraliz-Request-Id": {
                "schema": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "X-Aztraliz-API-Version": {
                "schema": {
                  "type": "string",
                  "const": "1.1"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AttachmentResponse"
                }
              }
            }
          },
          "201": {
            "description": "Resource persisted",
            "headers": {
              "X-Aztraliz-Request-Id": {
                "schema": {
                  "type": "string",
                  "format": "uuid"
                }
              },
              "X-Aztraliz-API-Version": {
                "schema": {
                  "type": "string",
                  "const": "1.1"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AttachmentResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400"
          },
          "401": {
            "$ref": "#/components/responses/Error401"
          },
          "403": {
            "$ref": "#/components/responses/Error403"
          },
          "404": {
            "$ref": "#/components/responses/Error404"
          },
          "429": {
            "$ref": "#/components/responses/Error429"
          },
          "503": {
            "$ref": "#/components/responses/Error503"
          },
          "409": {
            "$ref": "#/components/responses/Error409"
          },
          "413": {
            "$ref": "#/components/responses/Error413"
          },
          "415": {
            "$ref": "#/components/responses/Error415"
          },
          "410": {
            "$ref": "#/components/responses/Error410"
          }
        },
        "x-required-scopes": [
          "messages:write"
        ],
        "parameters": [
          {
            "name": "conversationId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            },
            "description": "Opaque Aztraliz ID"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "externalId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 128
                  },
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                },
                "required": [
                  "externalId",
                  "file"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "description": "One file, 1 byte to 25 MiB. Stable externalId deduplicates by bytes/name/MIME. Unused files expire after 24h. Uploaded files are not messages; use the returned ID in messages attachments. Does not accept external URLs. Requires administrator opt-in and GET /me capabilities.media=true."
      }
    }
  },
  "webhooks": {
    "message.created": {
      "post": {
        "summary": "An advisor replied from Aztraliz",
        "description": "POST to configured public HTTPS receiver. Verify HMAC-SHA256(secret, timestamp + \".\" + exact raw body), reject timestamps outside 300 seconds, persist before replying 2xx. At least once delivery; deduplicate event IDs and upsert messages. No ordering guarantee. Timeout 10 seconds, up to 12 attempts, no redirects. Same event ID/content with fresh timestamp/signature. Event status is a creation snapshot.",
        "parameters": [
          {
            "name": "X-Aztraliz-Event-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Matches event.id"
          },
          {
            "name": "X-Aztraliz-Timestamp",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Unix seconds"
          },
          {
            "name": "X-Aztraliz-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "v1=<64 lowercase hex characters>"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Event durably saved or duplicate"
          },
          "500": {
            "description": "Could not save; retry required"
          }
        }
      }
    },
    "conversation.deleted": {
      "post": {
        "summary": "An administrator deleted a connected-app conversation",
        "description": "Sent to the same signed webhook for deletions from web, iOS or Android, including text-only integrations. Deletion and outbox commit atomically. No message/thread relation is needed for delivery. Verify the same HMAC and commit the event ID, a permanent tombstone keyed by integrationId and conversation.id, local history deletion and downstream notification before replying 2xx. Delete only this Aztraliz conversation ID; externalId can be reused by a newly created conversation. Ignore late message.created events for tombstoned IDs. At least once, no ordering guarantee, 10s timeout, up to 12 attempts, same event ID/payload on retries; an administrator can retry a dead delivery. Paused integrations retain the event until reactivated; revocation cancels pending webhooks. No media opt-in or new credentials required.",
        "parameters": [
          {
            "name": "X-Aztraliz-Event-Id",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Matches event.id"
          },
          {
            "name": "X-Aztraliz-Timestamp",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Unix seconds"
          },
          {
            "name": "X-Aztraliz-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "v1=<64 lowercase hex characters>"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConversationDeletedWebhookEvent"
              },
              "example": {
                "id": "47a67417-ed2d-4fe3-9b59-15d72b6c9e5a",
                "type": "conversation.deleted",
                "apiVersion": "1.1",
                "createdAt": "2026-10-12T18:00:00.000Z",
                "integrationId": "integration-id",
                "data": {
                  "conversation": {
                    "id": "old-conversation-id",
                    "externalId": "support-order-482"
                  },
                  "deletedAt": "2026-10-12T18:00:00.000Z"
                }
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Deletion and tombstone committed, or duplicate/already absent conversation"
          },
          "500": {
            "description": "Could not save; retry required"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "MessagingToken": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "azm_<opaque token>"
      }
    },
    "schemas": {
      "Contact": {
        "type": "object",
        "properties": {
          "externalId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120
          },
          "phone": {
            "type": "string",
            "maxLength": 40,
            "description": "Optional international phone number, including country code. Matched to one customer in the same business using phone or WhatsApp; Mexican 52 and legacy 521 prefixes are equivalent. Opaque externalId is never used as a phone number."
          }
        },
        "required": [
          "externalId",
          "name"
        ],
        "additionalProperties": false
      },
      "ConversationInput": {
        "type": "object",
        "properties": {
          "externalId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "contact": {
            "$ref": "#/components/schemas/Contact"
          },
          "context": {
            "type": "object",
            "additionalProperties": true,
            "description": "Application context; at most 4096 bytes of serialized JSON, immutable on replay."
          }
        },
        "required": [
          "externalId",
          "contact"
        ],
        "additionalProperties": false
      },
      "Conversation": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "externalId": {
            "type": "string"
          },
          "contact": {
            "$ref": "#/components/schemas/Contact"
          },
          "context": {
            "type": "object",
            "additionalProperties": true,
            "description": "Application context; at most 4096 bytes of serialized JSON, immutable on replay."
          },
          "status": {
            "type": "string",
            "enum": [
              "new",
              "open",
              "pending_agent",
              "pending_customer",
              "resolved",
              "closed",
              "escalated"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "externalId",
          "contact",
          "context",
          "status",
          "createdAt"
        ],
        "additionalProperties": false
      },
      "MessageInput": {
        "type": "object",
        "properties": {
          "externalId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "text": {
            "type": "string",
            "minLength": 0,
            "maxLength": 4000,
            "description": "Optional caption with media, at most 4000 UTF-8 bytes after trimming. Required and nonempty for text messages."
          },
          "replyTo": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64
          },
          "attachments": {
            "type": "array",
            "minItems": 1,
            "maxItems": 8,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            },
            "description": "Managed upload IDs from this conversation/uploader. Attach within 24h; at most 100 MiB combined. One attachment belongs to one logical message."
          }
        },
        "required": [
          "externalId"
        ],
        "additionalProperties": false,
        "anyOf": [
          {
            "required": [
              "text"
            ],
            "properties": {
              "text": {
                "minLength": 1
              }
            }
          },
          {
            "required": [
              "attachments"
            ]
          }
        ]
      },
      "Message": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "externalId": {
            "type": [
              "string",
              "null"
            ]
          },
          "direction": {
            "type": "string",
            "enum": [
              "inbound",
              "outbound"
            ]
          },
          "type": {
            "type": "string",
            "enum": [
              "text",
              "media"
            ]
          },
          "text": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "sent",
              "delivered",
              "read",
              "failed"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "deliveredAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "readAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "replyTo": {
            "type": [
              "string",
              "null"
            ]
          },
          "sender": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              }
            },
            "required": [
              "name"
            ],
            "additionalProperties": false
          },
          "attachments": {
            "type": "array",
            "minItems": 1,
            "maxItems": 8,
            "items": {
              "$ref": "#/components/schemas/Attachment"
            }
          }
        },
        "required": [
          "id",
          "externalId",
          "direction",
          "type",
          "text",
          "status",
          "createdAt",
          "deliveredAt",
          "readAt",
          "replyTo"
        ],
        "additionalProperties": false
      },
      "ReceiptInput": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "delivered",
              "read"
            ]
          }
        },
        "required": [
          "status"
        ],
        "additionalProperties": false
      },
      "IntegrationInfo": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "appKey": {
            "type": "string"
          },
          "iconUrl": {
            "type": ["string", "null"],
            "format": "uri",
            "readOnly": true,
            "description": "Optional HTTPS app icon configured by the administrator; null when no icon is selected."
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "conversations:read",
                "conversations:write",
                "messages:read",
                "messages:write",
                "receipts:write"
              ]
            }
          },
          "apiVersion": {
            "type": "string",
            "const": "1.1"
          },
          "capabilities": {
            "type": "object",
            "properties": {
              "media": {
                "type": "boolean"
              }
            },
            "required": [
              "media"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "id",
          "name",
          "appKey",
          "scopes",
          "apiVersion",
          "capabilities"
        ],
        "additionalProperties": false
      },
      "PageMeta": {
        "type": "object",
        "properties": {
          "hasMore": {
            "type": "boolean"
          },
          "nextCursor": {
            "type": [
              "string",
              "null"
            ]
          },
          "lastCursor": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "hasMore",
          "nextCursor",
          "lastCursor"
        ],
        "additionalProperties": false
      },
      "ReplayMeta": {
        "type": "object",
        "properties": {
          "replayed": {
            "type": "boolean"
          }
        },
        "required": [
          "replayed"
        ],
        "additionalProperties": false
      },
      "Error": {
        "type": "object",
        "properties": {
          "ok": {
            "const": false
          },
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            },
            "required": [
              "code",
              "message"
            ],
            "additionalProperties": false
          },
          "requestId": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "ok",
          "error",
          "requestId"
        ],
        "additionalProperties": false
      },
      "WebhookEvent": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "type": {
            "type": "string",
            "const": "message.created"
          },
          "apiVersion": {
            "type": "string",
            "enum": [
              "1.0",
              "1.1"
            ],
            "description": "message.created uses 1.0 for text-only integrations and 1.1 after the administrator enables media."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "integrationId": {
            "type": "string"
          },
          "data": {
            "type": "object",
            "properties": {
              "conversation": {
                "$ref": "#/components/schemas/Conversation"
              },
              "message": {
                "$ref": "#/components/schemas/Message"
              }
            },
            "required": [
              "conversation",
              "message"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "id",
          "type",
          "apiVersion",
          "createdAt",
          "integrationId",
          "data"
        ],
        "additionalProperties": false
      },
      "ConversationResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "const": true
          },
          "data": {
            "$ref": "#/components/schemas/Conversation"
          },
          "requestId": {
            "type": "string",
            "format": "uuid"
          },
          "meta": {
            "$ref": "#/components/schemas/ReplayMeta"
          }
        },
        "required": [
          "ok",
          "data",
          "requestId"
        ],
        "additionalProperties": false
      },
      "MessageResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "const": true
          },
          "data": {
            "$ref": "#/components/schemas/Message"
          },
          "requestId": {
            "type": "string",
            "format": "uuid"
          },
          "meta": {
            "$ref": "#/components/schemas/ReplayMeta"
          }
        },
        "required": [
          "ok",
          "data",
          "requestId"
        ],
        "additionalProperties": false
      },
      "IntegrationResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "const": true
          },
          "data": {
            "$ref": "#/components/schemas/IntegrationInfo"
          },
          "requestId": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "ok",
          "data",
          "requestId"
        ],
        "additionalProperties": false
      },
      "ConversationsResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "const": true
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Conversation"
            }
          },
          "requestId": {
            "type": "string",
            "format": "uuid"
          },
          "meta": {
            "$ref": "#/components/schemas/PageMeta"
          }
        },
        "required": [
          "ok",
          "data",
          "requestId",
          "meta"
        ],
        "additionalProperties": false
      },
      "MessagesResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "const": true
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Message"
            }
          },
          "requestId": {
            "type": "string",
            "format": "uuid"
          },
          "meta": {
            "$ref": "#/components/schemas/PageMeta"
          }
        },
        "required": [
          "ok",
          "data",
          "requestId",
          "meta"
        ],
        "additionalProperties": false
      },
      "Attachment": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string",
            "maxLength": 180
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "HTTPS URL managed by Aztraliz. Treat as a shareable storage URL."
          },
          "mime": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "image",
              "video",
              "audio",
              "document"
            ]
          },
          "sizeBytes": {
            "type": "integer",
            "minimum": 1,
            "maximum": 26214400
          },
          "sha256": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$",
            "description": "SHA-256 of bytes received at upload; the image storage provider may optimize images."
          }
        },
        "required": [
          "id",
          "name",
          "url",
          "mime",
          "kind",
          "sizeBytes",
          "sha256"
        ],
        "additionalProperties": false
      },
      "AttachmentResponse": {
        "type": "object",
        "properties": {
          "ok": {
            "const": true
          },
          "data": {
            "$ref": "#/components/schemas/Attachment"
          },
          "requestId": {
            "type": "string",
            "format": "uuid"
          },
          "meta": {
            "$ref": "#/components/schemas/ReplayMeta"
          }
        },
        "required": [
          "ok",
          "data",
          "requestId"
        ],
        "additionalProperties": false
      },
      "ConversationDeletedWebhookEvent": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "type": {
            "type": "string",
            "const": "conversation.deleted"
          },
          "apiVersion": {
            "type": "string",
            "const": "1.1",
            "description": "This lifecycle event uses 1.1 for every integration, including text-only integrations."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "integrationId": {
            "type": "string"
          },
          "data": {
            "type": "object",
            "properties": {
              "conversation": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "Deleted Aztraliz ID. Use this ID with integrationId for tombstones and removal, never externalId alone."
                  },
                  "externalId": {
                    "type": "string",
                    "description": "Original app identifier, for correlation only; a new Aztraliz conversation may reuse it."
                  }
                },
                "required": [
                  "id",
                  "externalId"
                ],
                "additionalProperties": false
              },
              "deletedAt": {
                "type": "string",
                "format": "date-time",
                "description": "Time of the deletion transaction, equal to event.createdAt; delivery may occur later."
              }
            },
            "required": [
              "conversation",
              "deletedAt"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "id",
          "type",
          "apiVersion",
          "createdAt",
          "integrationId",
          "data"
        ],
        "additionalProperties": false
      }
    },
    "responses": {
      "Error400": {
        "description": "Invalid request, JSON or cursor",
        "headers": {
          "X-Aztraliz-Request-Id": {
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          "X-Aztraliz-API-Version": {
            "schema": {
              "type": "string",
              "const": "1.1"
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Error401": {
        "description": "Missing, invalid or inactive credential",
        "headers": {
          "X-Aztraliz-Request-Id": {
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          "X-Aztraliz-API-Version": {
            "schema": {
              "type": "string",
              "const": "1.1"
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Error403": {
        "description": "Missing required scope",
        "headers": {
          "X-Aztraliz-Request-Id": {
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          "X-Aztraliz-API-Version": {
            "schema": {
              "type": "string",
              "const": "1.1"
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Error404": {
        "description": "Resource does not exist or is outside this integration",
        "headers": {
          "X-Aztraliz-Request-Id": {
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          "X-Aztraliz-API-Version": {
            "schema": {
              "type": "string",
              "const": "1.1"
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Error409": {
        "description": "Identifier/content or contact conflict",
        "headers": {
          "X-Aztraliz-Request-Id": {
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          "X-Aztraliz-API-Version": {
            "schema": {
              "type": "string",
              "const": "1.1"
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Error413": {
        "description": "JSON body, file or multipart/message size limit exceeded; see media limits.",
        "headers": {
          "X-Aztraliz-Request-Id": {
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          "X-Aztraliz-API-Version": {
            "schema": {
              "type": "string",
              "const": "1.1"
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Error415": {
        "description": "Unsupported request content type, file MIME or mismatched file signature.",
        "headers": {
          "X-Aztraliz-Request-Id": {
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          "X-Aztraliz-API-Version": {
            "schema": {
              "type": "string",
              "const": "1.1"
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Error429": {
        "description": "Rate limit exceeded",
        "headers": {
          "X-Aztraliz-Request-Id": {
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          "X-Aztraliz-API-Version": {
            "schema": {
              "type": "string",
              "const": "1.1"
            }
          },
          "Retry-After": {
            "schema": {
              "type": "string"
            },
            "description": "Seconds to wait"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Error503": {
        "description": "Service unavailable; retry with the same external identifier",
        "headers": {
          "X-Aztraliz-Request-Id": {
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          "X-Aztraliz-API-Version": {
            "schema": {
              "type": "string",
              "const": "1.1"
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Error410": {
        "description": "ATTACHMENT_EXPIRED: use a new upload ID after expiration.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    }
  }
}
