{
  "openapi": "3.1.0",
  "info": {
    "title": "Liberrex AI & Agents API",
    "version": "v1",
    "description": "REST API v1 (API keys key_id:secret), agent webhooks and the Quality ingestion API. Documentation: https://ai.liberrex.com/docs"
  },
  "servers": [
    {
      "url": "https://ai-api.liberrex.com",
      "description": "Liberrex cloud"
    },
    {
      "url": "https://{host}",
      "description": "Your deployment",
      "variables": {
        "host": {
          "default": "YOUR-LIBERREX-HOST"
        }
      }
    }
  ],
  "security": [
    {
      "bearerApiKey": []
    },
    {
      "headerApiKey": []
    }
  ],
  "tags": [
    {
      "name": "Service"
    },
    {
      "name": "Keys"
    },
    {
      "name": "Agents"
    },
    {
      "name": "Conversations"
    },
    {
      "name": "Usage"
    },
    {
      "name": "Agent webhooks"
    },
    {
      "name": "Quality"
    }
  ],
  "paths": {
    "/api/v1/health": {
      "get": {
        "operationId": "getHealth",
        "tags": [
          "Service"
        ],
        "summary": "Check the service",
        "security": [],
        "description": "No key, not rate limited.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "const": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/Health"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/me": {
      "get": {
        "operationId": "getMe",
        "tags": [
          "Keys"
        ],
        "summary": "Retrieve the current key",
        "x-access-level": "read",
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data"
                  ],
                  "properties": {
                    "success": {
                      "const": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/Me"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/v1/agents": {
      "get": {
        "operationId": "listAgents",
        "tags": [
          "Agents"
        ],
        "summary": "List agents",
        "x-access-level": "read",
        "description": "Not paginated: every agent in the key scope, most recently updated first.",
        "parameters": [
          {
            "name": "search",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Case-insensitive substring of the agent name."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data"
                  ],
                  "properties": {
                    "success": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "required": [
                        "items",
                        "total"
                      ],
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Agent"
                          }
                        },
                        "total": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/v1/agents/{agent_uuid}": {
      "get": {
        "operationId": "getAgent",
        "tags": [
          "Agents"
        ],
        "summary": "Retrieve an agent",
        "x-access-level": "read",
        "parameters": [
          {
            "name": "agent_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data"
                  ],
                  "properties": {
                    "success": {
                      "const": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/Agent"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/v1/agents/{agent_uuid}/messages": {
      "post": {
        "operationId": "sendMessage",
        "tags": [
          "Agents"
        ],
        "summary": "Send a message",
        "x-access-level": "execute",
        "description": "Synchronous. Without session_id a new conversation starts on the api channel. At most 200 exchanges per conversation.",
        "parameters": [
          {
            "name": "agent_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MessageRequest"
              },
              "example": {
                "message": "Hello, I lost my card",
                "metadata": {
                  "crm_id": "C-42"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data"
                  ],
                  "properties": {
                    "success": {
                      "const": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/MessageReply"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "invalid_request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "insufficient_credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "description": "conversation_closed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/v1/conversations": {
      "get": {
        "operationId": "listConversations",
        "tags": [
          "Conversations"
        ],
        "summary": "List conversations",
        "x-access-level": "read",
        "x-owner-permission": "read:transcripts",
        "parameters": [
          {
            "name": "agent",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "channel",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "in_progress",
                "completed",
                "hangup",
                "failed"
              ]
            }
          },
          {
            "name": "since",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "ISO 8601 date or date-time (UTC when no zone). Inclusive."
          },
          {
            "name": "until",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "ISO 8601 date or date-time. Exclusive."
          },
          {
            "name": "include_tests",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "1",
                "true",
                "yes"
              ]
            },
            "description": "Include playground tests (they are excluded by default unless channel is set)."
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data"
                  ],
                  "properties": {
                    "success": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "required": [
                        "items",
                        "pagination"
                      ],
                      "properties": {
                        "items": {
                          "type": "array",
                          "items": {
                            "$ref": "#/components/schemas/Conversation"
                          }
                        },
                        "pagination": {
                          "$ref": "#/components/schemas/Pagination"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "invalid_request (since/until)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/v1/conversations/{conversation_id}": {
      "get": {
        "operationId": "getConversation",
        "tags": [
          "Conversations"
        ],
        "summary": "Retrieve a conversation",
        "x-access-level": "read",
        "x-owner-permission": "read:transcripts",
        "parameters": [
          {
            "name": "conversation_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data"
                  ],
                  "properties": {
                    "success": {
                      "const": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/ConversationDetail"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/v1/conversations/{conversation_id}/end": {
      "post": {
        "operationId": "endConversation",
        "tags": [
          "Conversations"
        ],
        "summary": "End a conversation",
        "x-access-level": "execute",
        "description": "API conversations only. Runs the post-conversation analysis in the background when it is on. No body.",
        "parameters": [
          {
            "name": "conversation_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data"
                  ],
                  "properties": {
                    "success": {
                      "const": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/Conversation"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/v1/usage": {
      "get": {
        "operationId": "getUsage",
        "tags": [
          "Usage"
        ],
        "summary": "Retrieve usage",
        "x-access-level": "read",
        "responses": {
          "200": {
            "description": "OK",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "data"
                  ],
                  "properties": {
                    "success": {
                      "const": true
                    },
                    "data": {
                      "$ref": "#/components/schemas/Usage"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ServerError"
          }
        }
      }
    },
    "/api/workflows/{workflow_uuid}/webhook": {
      "post": {
        "operationId": "triggerAgentWebhook",
        "tags": [
          "Agent webhooks"
        ],
        "summary": "Trigger a task agent",
        "description": "Not part of the v1 envelope. When the agent has a secret, send X-Webhook-Secret or X-Liberrex-Signature (sha256=hex HMAC-SHA256 of the raw body with the secret). Body up to 1 MB. Per-agent rate limit (60/min by default).",
        "security": [
          {},
          {
            "webhookSecret": []
          },
          {
            "webhookSignature": []
          }
        ],
        "parameters": [
          {
            "name": "workflow_uuid",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object"
              }
            },
            "multipart/form-data": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Run finished",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "const": true
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "workflow_uuid": {
                          "type": "string"
                        },
                        "trigger_type": {
                          "const": "webhook"
                        },
                        "run_uuid": {
                          "type": "string"
                        },
                        "results": {
                          "type": "object"
                        },
                        "execution_data": {
                          "type": "object"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Workflow is not active",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid webhook secret",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookError"
                }
              }
            }
          },
          "404": {
            "description": "Workflow not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookError"
                }
              }
            }
          },
          "413": {
            "description": "Payload too large",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookError"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookError"
                }
              }
            }
          },
          "500": {
            "description": "The run failed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "const": false
                    },
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/quality/ingest": {
      "post": {
        "operationId": "ingestQualityInteractions",
        "tags": [
          "Quality"
        ],
        "summary": "Send interactions to Quality",
        "description": "One interaction or {\"interactions\": [...]} with 1 to 100 items. Duplicates (same channel and external_id) are skipped.",
        "security": [
          {
            "qualityBearer": []
          },
          {
            "qualityKey": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/QualityInteraction"
                  },
                  {
                    "type": "object",
                    "required": [
                      "interactions"
                    ],
                    "properties": {
                      "interactions": {
                        "type": "array",
                        "minItems": 1,
                        "maxItems": 100,
                        "items": {
                          "$ref": "#/components/schemas/QualityInteraction"
                        }
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "At least one interaction created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QualityResult"
                }
              }
            }
          },
          "200": {
            "description": "Nothing created (all duplicates or refused)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QualityResult"
                }
              }
            }
          },
          "400": {
            "description": "Invalid body, or plan / allowance / credits refusal",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QualityError"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or missing ingestion key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QualityError"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerApiKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "Authorization: Bearer key_id:secret"
      },
      "headerApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "key_id:secret"
      },
      "webhookSecret": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Webhook-Secret",
        "description": "The agent secret."
      },
      "webhookSignature": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Liberrex-Signature",
        "description": "sha256=<hex HMAC-SHA256 of the raw body, keyed with the agent secret>"
      },
      "qualityBearer": {
        "type": "http",
        "scheme": "bearer",
        "description": "Authorization: Bearer lqk_…"
      },
      "qualityKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Quality-Key",
        "description": "lqk_…"
      }
    },
    "headers": {
      "X-RateLimit-Limit": {
        "description": "Requests allowed per minute for the key.",
        "schema": {
          "type": "integer"
        }
      },
      "X-RateLimit-Remaining": {
        "description": "Requests left in the current clock minute.",
        "schema": {
          "type": "integer"
        }
      },
      "Retry-After": {
        "description": "Seconds until the counter resets.",
        "schema": {
          "type": "integer"
        }
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "unauthorized: missing, wrong, deactivated or expired key, or owner without access",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Forbidden": {
        "description": "forbidden (access level, owner permission, project) or plan_required",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "NotFound": {
        "description": "not_found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "RateLimited": {
        "description": "rate_limited",
        "headers": {
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/X-RateLimit-Limit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/X-RateLimit-Remaining"
          },
          "Retry-After": {
            "$ref": "#/components/headers/Retry-After"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "ServerError": {
        "description": "server_error",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "success",
          "message",
          "code"
        ],
        "properties": {
          "success": {
            "const": false
          },
          "message": {
            "type": "string",
            "description": "Readable message, in English unless Accept-Language is fr or ar."
          },
          "code": {
            "type": "string",
            "enum": [
              "invalid_request",
              "unauthorized",
              "insufficient_credits",
              "forbidden",
              "plan_required",
              "not_found",
              "conversation_closed",
              "rate_limited",
              "server_error"
            ]
          }
        }
      },
      "Health": {
        "type": "object",
        "required": [
          "status",
          "version",
          "time"
        ],
        "properties": {
          "status": {
            "type": "string",
            "const": "ok"
          },
          "version": {
            "type": "string",
            "const": "v1"
          },
          "time": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Me": {
        "type": "object",
        "required": [
          "key",
          "owner",
          "company",
          "plan"
        ],
        "properties": {
          "key": {
            "type": "object",
            "required": [
              "key_id",
              "name",
              "access_levels",
              "project",
              "rate_limit_per_minute",
              "expires_at",
              "created_at",
              "last_used_at"
            ],
            "properties": {
              "key_id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "access_levels": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "read",
                    "write",
                    "execute",
                    "transcribe",
                    "synthesize",
                    "admin"
                  ]
                }
              },
              "project": {
                "oneOf": [
                  {
                    "type": "object",
                    "properties": {
                      "uuid": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "name": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "uuid",
                      "name"
                    ]
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "rate_limit_per_minute": {
                "type": "integer",
                "minimum": 1,
                "maximum": 1000
              },
              "expires_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              },
              "created_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              },
              "last_used_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              }
            }
          },
          "owner": {
            "type": "object",
            "required": [
              "uuid",
              "name",
              "email",
              "role",
              "permissions"
            ],
            "properties": {
              "uuid": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "email": {
                "type": "string",
                "format": "email"
              },
              "role": {
                "type": "string"
              },
              "permissions": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          },
          "company": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            }
          },
          "plan": {
            "type": "string",
            "description": "Identifier of the plan in effect."
          }
        }
      },
      "Agent": {
        "type": "object",
        "required": [
          "uuid",
          "name",
          "description",
          "type",
          "project",
          "published",
          "published_version",
          "published_at",
          "accepts_messages",
          "channels",
          "webhook",
          "created_at",
          "updated_at"
        ],
        "properties": {
          "uuid": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "type": {
            "type": [
              "string",
              "null"
            ],
            "examples": [
              "voice_inbound",
              "voice_outbound",
              "chat",
              "messaging",
              "email",
              "task",
              "scheduled",
              "employee"
            ]
          },
          "project": {
            "oneOf": [
              {
                "type": "object",
                "properties": {
                  "uuid": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "name": {
                    "type": "string"
                  }
                },
                "required": [
                  "uuid",
                  "name"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "published": {
            "type": "boolean"
          },
          "published_version": {
            "type": [
              "integer",
              "null"
            ]
          },
          "published_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "accepts_messages": {
            "type": "boolean",
            "description": "The agent has a chat step and can answer POST /api/v1/agents/{agent_uuid}/messages."
          },
          "channels": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "integer"
                },
                "name": {
                  "type": "string"
                },
                "type": {
                  "type": "string"
                },
                "status": {
                  "type": "string"
                }
              }
            }
          },
          "webhook": {
            "oneOf": [
              {
                "type": "object",
                "required": [
                  "url",
                  "secret_required",
                  "accepts_runs"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "description": "Path of the trigger, relative to the base URL."
                  },
                  "secret_required": {
                    "type": "boolean"
                  },
                  "accepts_runs": {
                    "type": "boolean"
                  }
                }
              },
              {
                "type": "null"
              }
            ]
          },
          "created_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "Contact": {
        "type": "object",
        "description": "API conversations: name, email, phone. Other channels: name, address.",
        "properties": {
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "email": {
            "type": [
              "string",
              "null"
            ]
          },
          "phone": {
            "type": [
              "string",
              "null"
            ]
          },
          "address": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Conversation": {
        "type": "object",
        "required": [
          "id",
          "agent",
          "channel",
          "source",
          "status",
          "test",
          "contact",
          "turns",
          "started_at",
          "ended_at",
          "duration_seconds",
          "summary"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "agent": {
            "oneOf": [
              {
                "type": "object",
                "properties": {
                  "uuid": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "name": {
                    "type": "string"
                  }
                },
                "required": [
                  "uuid",
                  "name"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "channel": {
            "type": "string",
            "examples": [
              "api",
              "web_chat",
              "whatsapp",
              "sms",
              "telegram",
              "messenger",
              "instagram",
              "email",
              "sip",
              "playground"
            ]
          },
          "source": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "in_progress",
              "completed",
              "hangup",
              "failed"
            ]
          },
          "test": {
            "type": "boolean"
          },
          "contact": {
            "$ref": "#/components/schemas/Contact"
          },
          "turns": {
            "type": "integer"
          },
          "started_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "ended_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "duration_seconds": {
            "type": [
              "number",
              "null"
            ]
          },
          "summary": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "ConversationDetail": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Conversation"
          },
          {
            "type": "object",
            "required": [
              "messages",
              "metadata",
              "analysis"
            ],
            "properties": {
              "messages": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "turn": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "role": {
                      "type": "string",
                      "enum": [
                        "user",
                        "assistant"
                      ]
                    },
                    "text": {
                      "type": "string"
                    },
                    "at": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "ISO 8601 with +00:00 offset."
                    }
                  }
                }
              },
              "metadata": {
                "type": "object"
              },
              "analysis": {
                "oneOf": [
                  {
                    "type": "object",
                    "properties": {
                      "success": {},
                      "summary": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "fields": {
                        "type": [
                          "object",
                          "null"
                        ]
                      },
                      "analyzed_at": {
                        "type": [
                          "string",
                          "null"
                        ]
                      }
                    }
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            }
          }
        ]
      },
      "MessageRequest": {
        "type": "object",
        "required": [
          "message"
        ],
        "properties": {
          "message": {
            "type": "string",
            "minLength": 1,
            "maxLength": 4000
          },
          "session_id": {
            "type": "string",
            "description": "Continue an API conversation of the same agent that is in progress."
          },
          "contact": {
            "type": "object",
            "description": "New conversations only; longer values are cut.",
            "properties": {
              "name": {
                "type": "string",
                "maxLength": 120
              },
              "email": {
                "type": "string",
                "maxLength": 254
              },
              "phone": {
                "type": "string",
                "maxLength": 40
              }
            }
          },
          "metadata": {
            "type": "object",
            "description": "New conversations only; at most 4 KB once serialised."
          }
        }
      },
      "MessageReply": {
        "type": "object",
        "required": [
          "reply",
          "session_id",
          "conversation_id",
          "agent",
          "handoffs",
          "turn",
          "version",
          "latency_ms"
        ],
        "properties": {
          "reply": {
            "type": "string"
          },
          "session_id": {
            "type": "string"
          },
          "conversation_id": {
            "type": "string"
          },
          "agent": {
            "type": "object",
            "description": "The agent that wrote this reply (after a transfer: the colleague who answered).",
            "properties": {
              "uuid": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              },
              "title": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "avatar": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Path of the avatar image, or null."
              }
            },
            "required": [
              "uuid",
              "name"
            ]
          },
          "turn": {
            "type": "integer",
            "minimum": 1
          },
          "version": {
            "type": "string",
            "examples": [
              "v3",
              "draft"
            ]
          },
          "latency_ms": {
            "type": "integer"
          },
          "handoffs": {
            "type": "array",
            "description": "Transfers that happened while answering this message (empty when none).",
            "items": {
              "type": "object",
              "properties": {
                "at": {
                  "type": "string",
                  "format": "date-time"
                },
                "from_uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "from_name": {
                  "type": "string"
                },
                "from_title": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "to_uuid": {
                  "type": "string",
                  "format": "uuid"
                },
                "to_name": {
                  "type": "string"
                },
                "to_title": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "reason": {
                  "type": "string"
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "transfer",
                    "escalation"
                  ]
                }
              },
              "required": [
                "from_uuid",
                "to_uuid",
                "kind"
              ]
            }
          }
        }
      },
      "Pagination": {
        "type": "object",
        "required": [
          "page",
          "per_page",
          "total",
          "pages"
        ],
        "properties": {
          "page": {
            "type": "integer"
          },
          "per_page": {
            "type": "integer"
          },
          "total": {
            "type": "integer"
          },
          "pages": {
            "type": "integer"
          }
        }
      },
      "Usage": {
        "type": "object",
        "required": [
          "plan",
          "balance",
          "period",
          "api_key"
        ],
        "properties": {
          "plan": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "subscribed_plan": {
                "type": "string"
              },
              "status": {
                "type": "string"
              },
              "cycle": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "included_credits": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "overage": {
                "type": "boolean"
              }
            }
          },
          "balance": {
            "type": "object",
            "properties": {
              "plan": {
                "type": "number"
              },
              "purchased": {
                "type": "number"
              },
              "total": {
                "type": "number"
              }
            }
          },
          "period": {
            "type": "object",
            "properties": {
              "start": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              },
              "end": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              },
              "total_credits": {
                "type": "number"
              },
              "items": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "metric": {
                      "type": "string"
                    },
                    "label": {
                      "type": "string"
                    },
                    "unit": {
                      "type": "string"
                    },
                    "quantity": {
                      "type": "number"
                    },
                    "credits": {
                      "type": "number"
                    },
                    "events": {
                      "type": "integer"
                    }
                  }
                }
              },
              "agents": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "agent_uuid": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "credits": {
                      "type": "number"
                    }
                  }
                }
              }
            }
          },
          "api_key": {
            "type": "object",
            "properties": {
              "key_id": {
                "type": "string"
              },
              "requests_this_period": {
                "type": "integer"
              },
              "rate_limit_per_minute": {
                "type": "integer"
              }
            }
          }
        }
      },
      "WebhookError": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string"
          }
        }
      },
      "QualityMessage": {
        "type": "object",
        "required": [
          "text"
        ],
        "description": "Aliases accepted: text (body, content, message), role (sender_type), author (from, name, sender, speaker), email (address), at (timestamp, sent_at, date, created_at).",
        "properties": {
          "text": {
            "type": "string",
            "maxLength": 6000
          },
          "role": {
            "type": "string"
          },
          "author": {
            "type": "string",
            "maxLength": 80
          },
          "email": {
            "type": "string"
          },
          "at": {
            "type": [
              "string",
              "number"
            ]
          }
        }
      },
      "QualityInteraction": {
        "type": "object",
        "required": [
          "channel",
          "messages"
        ],
        "description": "Aliases accepted: messages (turns, transcript), external_id (id, conversation_id), subchannel (source_channel), subject (title), agent_name (agent), occurred_at (started_at, date).",
        "properties": {
          "channel": {
            "type": "string",
            "enum": [
              "call",
              "email",
              "chat"
            ]
          },
          "messages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/QualityMessage"
            },
            "maxItems": 400
          },
          "external_id": {
            "type": "string",
            "maxLength": 255
          },
          "subchannel": {
            "type": "string",
            "maxLength": 30
          },
          "subject": {
            "type": "string",
            "maxLength": 300
          },
          "agent_name": {
            "type": "string",
            "maxLength": 120
          },
          "team": {
            "type": "string",
            "maxLength": 120
          },
          "agent_type": {
            "type": "string",
            "description": "ai, otherwise human."
          },
          "direction": {
            "type": "string",
            "enum": [
              "inbound",
              "outbound"
            ]
          },
          "occurred_at": {
            "type": [
              "string",
              "number"
            ]
          }
        }
      },
      "QualityError": {
        "type": "object",
        "required": [
          "success",
          "message"
        ],
        "properties": {
          "success": {
            "const": false
          },
          "message": {
            "type": "string"
          }
        }
      },
      "QualityResult": {
        "type": "object",
        "properties": {
          "success": {
            "const": true
          },
          "data": {
            "type": "object",
            "properties": {
              "created": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "external_id": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "channel": {
                      "type": "string"
                    }
                  }
                }
              },
              "duplicates": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "errors": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "index": {
                      "type": "integer"
                    },
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}