{
 "openapi": "3.1.0",
 "info": {
  "title": "ResponseCX Public API",
  "version": "1.0.0",
  "description": "Build and manage AI support agents programmatically. Authenticate with an organization API key (`Authorization: Bearer rcx_\u2026`); every response is scoped to the organization that owns the key. The same capabilities are available over MCP at POST /api/mcp. Resources are retired with `activated: false` rather than deleted, which is reversible and preserves history. The single exception is a knowledge document: a stored fact has no activated flag, so DELETE is the only way to stop it being retrieved."
 },
 "servers": [
  {
   "url": "https://response.stateset.com"
  }
 ],
 "components": {
  "securitySchemes": {
   "ApiKeyAuth": {
    "type": "http",
    "scheme": "bearer",
    "bearerFormat": "rcx_\u2026"
   }
  },
  "schemas": {
   "CreateAgent": {
    "type": "object",
    "properties": {
     "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200
     },
     "type": {
      "type": "string",
      "minLength": 1,
      "maxLength": 100,
      "description": "One of: assistant, customer_service, sales."
     },
     "description": {
      "type": "string",
      "maxLength": 5000
     },
     "instructions": {
      "type": "string",
      "maxLength": 50000,
      "description": "The system prompt / persona."
     },
     "goal": {
      "type": "string",
      "maxLength": 2000
     },
     "role": {
      "type": "string",
      "maxLength": 2000
     },
     "activated": {
      "type": "boolean"
     }
    },
    "required": [
     "name",
     "type"
    ],
    "additionalProperties": false
   },
   "UpdateAgent": {
    "type": "object",
    "properties": {
     "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200
     },
     "type": {
      "type": "string",
      "minLength": 1,
      "maxLength": 100,
      "description": "One of: assistant, customer_service, sales."
     },
     "description": {
      "type": "string",
      "maxLength": 5000
     },
     "instructions": {
      "type": "string",
      "maxLength": 50000,
      "description": "The system prompt / persona."
     },
     "goal": {
      "type": "string",
      "maxLength": 2000
     },
     "role": {
      "type": "string",
      "maxLength": 2000
     },
     "activated": {
      "type": "boolean"
     }
    },
    "additionalProperties": false
   },
   "ProvisionAgent": {
    "type": "object",
    "properties": {
     "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200
     },
     "template_id": {
      "type": "string",
      "maxLength": 100,
      "description": "Seeds rules/attributes/examples from a starter template."
     },
     "type": {
      "type": "string",
      "minLength": 1,
      "maxLength": 100,
      "description": "One of: assistant, customer_service, sales."
     },
     "description": {
      "type": "string",
      "maxLength": 5000
     },
     "instructions": {
      "type": "string",
      "maxLength": 50000,
      "description": "The system prompt / persona."
     },
     "goal": {
      "type": "string",
      "maxLength": 2000
     },
     "role": {
      "type": "string",
      "maxLength": 2000
     },
     "activated": {
      "type": "boolean"
     },
     "rules": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "rule_name": {
         "type": "string",
         "minLength": 1,
         "maxLength": 200
        },
        "rule_type": {
         "type": "string",
         "minLength": 1,
         "maxLength": 100,
         "description": "One of: escalation, qualification, response, routing."
        },
        "description": {
         "type": "string",
         "maxLength": 5000
        },
        "activated": {
         "type": "boolean"
        },
        "conditions": {
         "type": "object",
         "properties": {
          "any": {
           "type": "array"
          },
          "all": {
           "type": "array"
          }
         },
         "additionalProperties": false,
         "description": "{any|all: [{field, operator, value}]}. Fields: company_size, confidence, intent, knowledge_sources, latest_message, missing_required_fields, timeline. Operators: contains_any, eq, exists, gte, in, lt, not_empty."
        },
        "actions": {
         "type": "array",
         "maxItems": 100,
         "description": "[{type, ...}]. Types: collect_fields, fallback, handoff, include_sources, require_context, require_source_for_claims, require_verification, response_pattern, tag."
        }
       },
       "required": [
        "rule_name",
        "rule_type"
       ],
       "additionalProperties": false
      },
      "maxItems": 50
     },
     "functions": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "function_name": {
         "type": "string",
         "minLength": 1,
         "maxLength": 200
        },
        "endpoint": {
         "type": "string",
         "minLength": 1,
         "maxLength": 2000,
         "description": "Public http(s) URL. Private and metadata addresses are rejected."
        },
        "method": {
         "type": "string",
         "minLength": 1,
         "maxLength": 20
        },
        "description": {
         "type": "string",
         "maxLength": 5000
        },
        "activated": {
         "type": "boolean"
        },
        "parameters": {
         "type": "array",
         "items": {
          "type": "object",
          "properties": {
           "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
           },
           "type": {
            "type": "string",
            "minLength": 1,
            "maxLength": 50
           },
           "description": {
            "type": "string",
            "maxLength": 1000
           },
           "required": {
            "type": "boolean"
           }
          },
          "required": [
           "name",
           "type"
          ],
          "additionalProperties": false
         },
         "maxItems": 100
        },
        "headers": {
         "type": "object",
         "additionalProperties": {
          "type": "string"
         }
        },
        "timeout": {
         "type": "integer",
         "minimum": 1000,
         "maximum": 300000
        }
       },
       "required": [
        "function_name",
        "endpoint",
        "method"
       ],
       "additionalProperties": false
      },
      "maxItems": 50
     },
     "settings": {
      "type": "object",
      "properties": {
       "model_name": {
        "type": "string",
        "maxLength": 200,
        "description": "e.g. \"gpt-4.1\", \"claude-sonnet-5\"."
       },
       "model_provider": {
        "type": "string",
        "maxLength": 100,
        "description": "e.g. \"openai\", \"anthropic\"."
       },
       "model_type": {
        "type": "string",
        "maxLength": 100
       },
       "temperature": {
        "type": "number",
        "minimum": 0,
        "maximum": 2
       },
       "max_tokens": {
        "type": "integer",
        "minimum": 1,
        "maximum": 128000
       },
       "top_p": {
        "type": "number",
        "minimum": 0,
        "maximum": 1
       },
       "escalation_tag_name": {
        "type": "string",
        "maxLength": 200
       },
       "escalation_team_id": {
        "type": "string",
        "maxLength": 200
       },
       "agent_take_over_tag": {
        "type": "string",
        "maxLength": 200
       }
      },
      "additionalProperties": false,
      "description": "Model config. Defaults to the template's when a template is used."
     }
    },
    "required": [
     "name"
    ],
    "additionalProperties": false
   },
   "AgentSettings": {
    "type": "object",
    "properties": {
     "model_name": {
      "type": "string",
      "maxLength": 200,
      "description": "e.g. \"gpt-4.1\", \"claude-sonnet-5\"."
     },
     "model_provider": {
      "type": "string",
      "maxLength": 100,
      "description": "e.g. \"openai\", \"anthropic\"."
     },
     "model_type": {
      "type": "string",
      "maxLength": 100
     },
     "temperature": {
      "type": "number",
      "minimum": 0,
      "maximum": 2
     },
     "max_tokens": {
      "type": "integer",
      "minimum": 1,
      "maximum": 128000
     },
     "top_p": {
      "type": "number",
      "minimum": 0,
      "maximum": 1
     },
     "escalation_tag_name": {
      "type": "string",
      "maxLength": 200
     },
     "escalation_team_id": {
      "type": "string",
      "maxLength": 200
     },
     "agent_take_over_tag": {
      "type": "string",
      "maxLength": 200
     }
    },
    "additionalProperties": false
   },
   "CreateRule": {
    "type": "object",
    "properties": {
     "rule_name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200
     },
     "rule_type": {
      "type": "string",
      "minLength": 1,
      "maxLength": 100,
      "description": "One of: escalation, qualification, response, routing."
     },
     "description": {
      "type": "string",
      "maxLength": 5000
     },
     "activated": {
      "type": "boolean"
     },
     "conditions": {
      "type": "object",
      "properties": {
       "any": {
        "type": "array"
       },
       "all": {
        "type": "array"
       }
      },
      "additionalProperties": false,
      "description": "{any|all: [{field, operator, value}]}. Fields: company_size, confidence, intent, knowledge_sources, latest_message, missing_required_fields, timeline. Operators: contains_any, eq, exists, gte, in, lt, not_empty."
     },
     "actions": {
      "type": "array",
      "maxItems": 100,
      "description": "[{type, ...}]. Types: collect_fields, fallback, handoff, include_sources, require_context, require_source_for_claims, require_verification, response_pattern, tag."
     }
    },
    "required": [
     "rule_name",
     "rule_type"
    ],
    "additionalProperties": false
   },
   "UpdateRule": {
    "type": "object",
    "properties": {
     "rule_name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200
     },
     "rule_type": {
      "type": "string",
      "minLength": 1,
      "maxLength": 100,
      "description": "One of: escalation, qualification, response, routing."
     },
     "description": {
      "type": "string",
      "maxLength": 5000
     },
     "activated": {
      "type": "boolean",
      "description": "Set false to retire the rule."
     },
     "conditions": {
      "type": "object",
      "properties": {
       "any": {
        "type": "array"
       },
       "all": {
        "type": "array"
       }
      },
      "additionalProperties": false,
      "description": "{any|all: [{field, operator, value}]}. Fields: company_size, confidence, intent, knowledge_sources, latest_message, missing_required_fields, timeline. Operators: contains_any, eq, exists, gte, in, lt, not_empty."
     },
     "actions": {
      "type": "array",
      "maxItems": 100,
      "description": "[{type, ...}]. Types: collect_fields, fallback, handoff, include_sources, require_context, require_source_for_claims, require_verification, response_pattern, tag."
     }
    },
    "additionalProperties": false
   },
   "CreateFunction": {
    "type": "object",
    "properties": {
     "function_name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200
     },
     "endpoint": {
      "type": "string",
      "minLength": 1,
      "maxLength": 2000,
      "description": "Public http(s) URL. Private and metadata addresses are rejected."
     },
     "method": {
      "type": "string",
      "minLength": 1,
      "maxLength": 20
     },
     "description": {
      "type": "string",
      "maxLength": 5000
     },
     "activated": {
      "type": "boolean"
     },
     "parameters": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "name": {
         "type": "string",
         "minLength": 1,
         "maxLength": 100
        },
        "type": {
         "type": "string",
         "minLength": 1,
         "maxLength": 50
        },
        "description": {
         "type": "string",
         "maxLength": 1000
        },
        "required": {
         "type": "boolean"
        }
       },
       "required": [
        "name",
        "type"
       ],
       "additionalProperties": false
      },
      "maxItems": 100
     },
     "headers": {
      "type": "object",
      "additionalProperties": {
       "type": "string"
      }
     },
     "timeout": {
      "type": "integer",
      "minimum": 1000,
      "maximum": 300000
     }
    },
    "required": [
     "function_name",
     "endpoint",
     "method"
    ],
    "additionalProperties": false
   },
   "UpdateFunction": {
    "type": "object",
    "properties": {
     "function_name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200
     },
     "endpoint": {
      "type": "string",
      "minLength": 1,
      "maxLength": 2000
     },
     "method": {
      "type": "string",
      "minLength": 1,
      "maxLength": 20
     },
     "description": {
      "type": "string",
      "maxLength": 5000
     },
     "activated": {
      "type": "boolean",
      "description": "Set false to retire the tool."
     },
     "parameters": {
      "type": "array",
      "items": {
       "type": "object",
       "properties": {
        "name": {
         "type": "string",
         "minLength": 1,
         "maxLength": 100
        },
        "type": {
         "type": "string",
         "minLength": 1,
         "maxLength": 50
        },
        "description": {
         "type": "string",
         "maxLength": 1000
        },
        "required": {
         "type": "boolean"
        }
       },
       "required": [
        "name",
        "type"
       ],
       "additionalProperties": false
      },
      "maxItems": 100
     },
     "headers": {
      "type": "object",
      "additionalProperties": {
       "type": "string"
      }
     },
     "timeout": {
      "type": "integer",
      "minimum": 1000,
      "maximum": 300000
     }
    },
    "additionalProperties": false
   },
   "CreateEval": {
    "type": "object",
    "properties": {
     "response_id": {
      "type": "string",
      "format": "uuid"
     },
     "preferred_output": {
      "type": "string",
      "minLength": 1,
      "maxLength": 50000
     },
     "user_message": {
      "type": "string",
      "maxLength": 50000
     },
     "non_preferred_output": {
      "type": "string",
      "maxLength": 50000
     },
     "agent_id": {
      "type": "string",
      "format": "uuid"
     },
     "name": {
      "type": "string",
      "maxLength": 200
     },
     "description": {
      "type": "string",
      "maxLength": 10000
     },
     "reason_type": {
      "type": "string",
      "maxLength": 100
     },
     "customer_impact": {
      "type": "string",
      "maxLength": 100
     }
    },
    "required": [
     "preferred_output"
    ],
    "additionalProperties": false
   },
   "ConnectShopify": {
    "type": "object",
    "properties": {
     "shop": {
      "type": "string",
      "minLength": 1,
      "maxLength": 100,
      "description": "The store handle or myshopify domain, e.g. \"acme\" or \"acme.myshopify.com\"."
     },
     "access_token": {
      "type": "string",
      "minLength": 10,
      "maxLength": 200,
      "description": "An Admin API access token (shpat_\u2026) from a custom app."
     },
     "confirm_replace": {
      "type": "boolean",
      "description": "Required (true) when the organization already has a Shopify connection \u2014 connecting replaces it."
     }
    },
    "required": [
     "shop",
     "access_token"
    ],
    "additionalProperties": false
   },
   "ConnectGorgias": {
    "type": "object",
    "properties": {
     "domain": {
      "type": "string",
      "minLength": 1,
      "maxLength": 100,
      "description": "The Gorgias account domain, e.g. \"acme\" or \"acme.gorgias.com\"."
     },
     "email": {
      "type": "string",
      "format": "email",
      "maxLength": 200,
      "description": "The Gorgias agent email the API key belongs to."
     },
     "api_key": {
      "type": "string",
      "minLength": 10,
      "maxLength": 200,
      "description": "An API key from Settings \u2192 You \u2192 REST API."
     },
     "confirm_replace": {
      "type": "boolean",
      "description": "Required (true) when the organization already has a Gorgias connection \u2014 connecting replaces it."
     }
    },
    "required": [
     "domain",
     "email",
     "api_key"
    ],
    "additionalProperties": false
   },
   "Agent": {
    "type": "object",
    "properties": {
     "object": {
      "type": "string",
      "const": "agent"
     },
     "id": {
      "type": "string"
     },
     "name": {
      "type": [
       "string",
       "null"
      ]
     },
     "type": {
      "type": [
       "string",
       "null"
      ]
     },
     "description": {
      "type": [
       "string",
       "null"
      ]
     },
     "activated": {
      "type": "boolean"
     },
     "goal": {
      "type": [
       "string",
       "null"
      ]
     },
     "role": {
      "type": [
       "string",
       "null"
      ]
     },
     "updated_at": {
      "type": [
       "string",
       "null"
      ]
     },
     "instructions": {
      "type": [
       "string",
       "null"
      ],
      "description": "Present on single-agent reads and writes only."
     },
     "settings": {
      "$ref": "#/components/schemas/AgentSettingsOut"
     }
    }
   },
   "AgentSettingsOut": {
    "type": "object",
    "properties": {
     "object": {
      "type": "string",
      "const": "agent.settings"
     },
     "configured": {
      "type": "boolean",
      "description": "False when no settings row exists yet (fields are all null)."
     }
    }
   },
   "Rule": {
    "type": "object",
    "properties": {
     "object": {
      "type": "string",
      "const": "rule"
     },
     "id": {
      "type": "string"
     },
     "name": {
      "type": [
       "string",
       "null"
      ]
     },
     "type": {
      "type": [
       "string",
       "null"
      ]
     },
     "description": {
      "type": [
       "string",
       "null"
      ]
     },
     "activated": {
      "type": "boolean"
     },
     "conditions": {},
     "actions": {},
     "agent_id": {
      "type": [
       "string",
       "null"
      ]
     }
    }
   },
   "Function": {
    "type": "object",
    "properties": {
     "object": {
      "type": "string",
      "const": "function"
     },
     "id": {
      "type": "string"
     },
     "name": {
      "type": [
       "string",
       "null"
      ]
     },
     "endpoint": {
      "type": [
       "string",
       "null"
      ]
     },
     "method": {
      "type": [
       "string",
       "null"
      ]
     },
     "description": {
      "type": [
       "string",
       "null"
      ]
     },
     "activated": {
      "type": "boolean"
     },
     "agent_id": {
      "type": [
       "string",
       "null"
      ]
     }
    }
   },
   "Response": {
    "type": "object",
    "properties": {
     "object": {
      "type": "string",
      "const": "response"
     },
     "id": {
      "type": "string"
     },
     "channel": {
      "type": [
       "string",
       "null"
      ]
     },
     "customer_message": {
      "type": [
       "string",
       "null"
      ]
     },
     "agent_response": {
      "type": [
       "string",
       "null"
      ]
     },
     "rating": {
      "type": [
       "string",
       "null"
      ]
     },
     "handled_by": {
      "type": [
       "string",
       "null"
      ]
     },
     "taken_over": {
      "type": "boolean"
     },
     "ticket_id": {
      "type": [
       "string",
       "null"
      ]
     },
     "workflow_id": {
      "type": [
       "string",
       "null"
      ]
     },
     "created_at": {
      "type": [
       "string",
       "null"
      ]
     }
    }
   },
   "Conversation": {
    "type": "object",
    "properties": {
     "object": {
      "type": "string",
      "const": "conversation"
     },
     "id": {
      "type": [
       "string",
       "null"
      ]
     },
     "channel": {
      "type": [
       "string",
       "null"
      ]
     },
     "status": {
      "type": [
       "string",
       "null"
      ]
     },
     "escalated": {
      "type": "boolean"
     },
     "rating": {
      "type": [
       "string",
       "null"
      ]
     },
     "agent_id": {
      "type": [
       "string",
       "null"
      ]
     },
     "subject": {
      "type": [
       "string",
       "null"
      ]
     },
     "tags": {},
     "created_at": {
      "type": [
       "string",
       "null"
      ]
     },
     "messages": {
      "type": "array",
      "items": {
       "$ref": "#/components/schemas/Message"
      },
      "description": "Single-conversation reads only (capped transcript)."
     }
    }
   },
   "Message": {
    "type": "object",
    "properties": {
     "object": {
      "type": "string",
      "const": "message"
     },
     "id": {
      "type": [
       "string",
       "null"
      ]
     },
     "body": {
      "type": [
       "string",
       "null"
      ]
     },
     "from_agent": {
      "type": "boolean"
     },
     "author": {
      "type": [
       "string",
       "null"
      ]
     },
     "created_at": {
      "type": [
       "string",
       "null"
      ]
     }
    }
   }
  }
 },
 "x-error-codes": {
  "description": "Stable machine-readable failure identifiers returned as `code`. Message text is for humans and may be reworded; branch on these instead. Several share a status \u2014 three different 404s are only distinguishable by code.",
  "codes": [
   "agent_limit_reached",
   "agent_not_found",
   "already_connected",
   "conversation_not_found",
   "eval_not_found",
   "function_not_found",
   "generation_timeout",
   "generation_unreachable",
   "idempotency_in_progress",
   "idempotency_key_reused",
   "invalid_api_key",
   "invalid_cursor",
   "invalid_request",
   "knowledge_not_configured",
   "knowledge_not_found",
   "knowledge_unavailable",
   "missing_scope",
   "not_created",
   "response_not_found",
   "rule_not_found",
   "service_unavailable",
   "unknown_template",
   "unsafe_endpoint"
  ]
 },
 "x-vocabulary": {
  "description": "Values this platform actually evaluates. An unrecognized rule_type or condition field is accepted but never matches at runtime.",
  "agent_types": [
   "assistant",
   "customer_service",
   "sales"
  ],
  "rule_types": [
   "escalation",
   "qualification",
   "response",
   "routing"
  ],
  "template_ids": [
   "support",
   "ecommerce",
   "sales",
   "general"
  ]
 },
 "paths": {
  "/api/v1/workspace": {
   "get": {
    "summary": "Orientation: agents, configuration state, and a suggested next action",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "agents:read",
    "x-rate-limit-per-minute": 120,
    "responses": {
     "200": {
      "description": "Workspace summary",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   }
  },
  "/api/v1/agents": {
   "get": {
    "summary": "List agents",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "agents:read",
    "x-rate-limit-per-minute": 120,
    "parameters": [
     {
      "name": "limit",
      "in": "query",
      "schema": {
       "type": "integer",
       "minimum": 1,
       "maximum": 100,
       "default": 25
      }
     },
     {
      "name": "offset",
      "in": "query",
      "schema": {
       "type": "integer",
       "minimum": 0,
       "default": 0
      }
     }
    ],
    "responses": {
     "200": {
      "description": "A list of agents",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "object": {
           "type": "string",
           "enum": [
            "list"
           ]
          },
          "data": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/Agent"
           }
          },
          "has_more": {
           "type": "boolean"
          },
          "next_cursor": {
           "type": "string",
           "description": "Keyset cursor for the next page \u2014 present only on cursor-capable lists with more rows."
          }
         }
        }
       }
      }
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   },
   "post": {
    "summary": "Create an agent",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "agents:write",
    "x-rate-limit-per-minute": 30,
    "parameters": [
     {
      "name": "Idempotency-Key",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string",
       "maxLength": 200
      },
      "description": "Optional client-generated key that makes the POST safe to retry: a repeat with the same key and body replays the original response instead of creating a duplicate."
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CreateAgent"
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "The created agent",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Agent"
        }
       }
      }
     },
     "400": {
      "description": "Invalid request. `issues` names the offending field(s)."
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "409": {
      "description": "Conflict \u2014 either the creation ceiling was reached for this organization (`agent_limit_reached`), or a request with the same Idempotency-Key is still in flight (`idempotency_in_progress`); retry the latter after the first attempt settles."
     },
     "422": {
      "description": "The Idempotency-Key was already used with a DIFFERENT request body (`idempotency_key_reused`). Reuse a key only to retry the identical request."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   }
  },
  "/api/v1/agents/provision": {
   "post": {
    "summary": "Build a complete agent \u2014 rules, tools and settings \u2014 in one atomic call",
    "description": "Preferred over create + configure + add_rule + add_function. Pass template_id to seed a proven ruleset.",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "agents:write",
    "x-rate-limit-per-minute": 10,
    "parameters": [
     {
      "name": "Idempotency-Key",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string",
       "maxLength": 200
      },
      "description": "Optional client-generated key that makes the POST safe to retry: a repeat with the same key and body replays the original response instead of creating a duplicate."
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ProvisionAgent"
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "The provisioned agent, with a summary of what was created",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Agent"
        }
       }
      }
     },
     "400": {
      "description": "Invalid request. `issues` names the offending field(s)."
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "409": {
      "description": "Conflict \u2014 either the creation ceiling was reached for this organization (`agent_limit_reached`), or a request with the same Idempotency-Key is still in flight (`idempotency_in_progress`); retry the latter after the first attempt settles."
     },
     "422": {
      "description": "The Idempotency-Key was already used with a DIFFERENT request body (`idempotency_key_reused`). Reuse a key only to retry the identical request."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   }
  },
  "/api/v1/agents/{id}": {
   "get": {
    "summary": "Get one agent, including its instructions",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "agents:read",
    "x-rate-limit-per-minute": 120,
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      },
      "description": "The agent id."
     }
    ],
    "responses": {
     "200": {
      "description": "The agent",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Agent"
        }
       }
      }
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "404": {
      "description": "Not found, or not in the organization that owns the key."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   },
   "patch": {
    "summary": "Update an agent; set activated:true to launch it",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "agents:write",
    "x-rate-limit-per-minute": 30,
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      },
      "description": "The agent id."
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/UpdateAgent"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The updated agent",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Agent"
        }
       }
      }
     },
     "400": {
      "description": "Invalid request. `issues` names the offending field(s)."
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "404": {
      "description": "Not found, or not in the organization that owns the key."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   }
  },
  "/api/v1/agents/{id}/settings": {
   "get": {
    "summary": "Read an agent's model and behaviour settings",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "agents:read",
    "x-rate-limit-per-minute": 120,
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      },
      "description": "The agent id."
     }
    ],
    "responses": {
     "200": {
      "description": "Settings",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "404": {
      "description": "Not found, or not in the organization that owns the key."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   },
   "put": {
    "summary": "Set model, temperature, token limits and escalation behaviour",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "agents:write",
    "x-rate-limit-per-minute": 30,
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      },
      "description": "The agent id."
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/AgentSettings"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Settings",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "400": {
      "description": "Invalid request. `issues` names the offending field(s)."
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "404": {
      "description": "Not found, or not in the organization that owns the key."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   }
  },
  "/api/v1/agents/{id}/rules": {
   "get": {
    "summary": "List an agent's guardrail rules",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "agents:read",
    "x-rate-limit-per-minute": 120,
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      },
      "description": "The agent id."
     },
     {
      "name": "limit",
      "in": "query",
      "schema": {
       "type": "integer",
       "minimum": 1,
       "maximum": 200,
       "default": 100
      }
     },
     {
      "name": "offset",
      "in": "query",
      "schema": {
       "type": "integer",
       "minimum": 0,
       "default": 0
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Rules",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "object": {
           "type": "string",
           "enum": [
            "list"
           ]
          },
          "data": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/Rule"
           }
          },
          "has_more": {
           "type": "boolean"
          },
          "next_cursor": {
           "type": "string",
           "description": "Keyset cursor for the next page \u2014 present only on cursor-capable lists with more rows."
          }
         }
        }
       }
      }
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "404": {
      "description": "Not found, or not in the organization that owns the key."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   },
   "post": {
    "summary": "Attach a guardrail rule",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "agents:write",
    "x-rate-limit-per-minute": 30,
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      },
      "description": "The agent id."
     },
     {
      "name": "Idempotency-Key",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string",
       "maxLength": 200
      },
      "description": "Optional client-generated key that makes the POST safe to retry: a repeat with the same key and body replays the original response instead of creating a duplicate."
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CreateRule"
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "The rule",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Rule"
        }
       }
      }
     },
     "400": {
      "description": "Invalid request. `issues` names the offending field(s)."
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "404": {
      "description": "Not found, or not in the organization that owns the key."
     },
     "409": {
      "description": "Conflict \u2014 either the creation ceiling was reached for this organization (`agent_limit_reached`), or a request with the same Idempotency-Key is still in flight (`idempotency_in_progress`); retry the latter after the first attempt settles."
     },
     "422": {
      "description": "The Idempotency-Key was already used with a DIFFERENT request body (`idempotency_key_reused`). Reuse a key only to retry the identical request."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   }
  },
  "/api/v1/agents/{id}/functions": {
   "get": {
    "summary": "List an agent's tools",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "agents:read",
    "x-rate-limit-per-minute": 120,
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      },
      "description": "The agent id."
     },
     {
      "name": "limit",
      "in": "query",
      "schema": {
       "type": "integer",
       "minimum": 1,
       "maximum": 200,
       "default": 100
      }
     },
     {
      "name": "offset",
      "in": "query",
      "schema": {
       "type": "integer",
       "minimum": 0,
       "default": 0
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Tools",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "object": {
           "type": "string",
           "enum": [
            "list"
           ]
          },
          "data": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/Function"
           }
          },
          "has_more": {
           "type": "boolean"
          },
          "next_cursor": {
           "type": "string",
           "description": "Keyset cursor for the next page \u2014 present only on cursor-capable lists with more rows."
          }
         }
        }
       }
      }
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "404": {
      "description": "Not found, or not in the organization that owns the key."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   },
   "post": {
    "summary": "Give the agent an API-call tool",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "agents:write",
    "x-rate-limit-per-minute": 30,
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      },
      "description": "The agent id."
     },
     {
      "name": "Idempotency-Key",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string",
       "maxLength": 200
      },
      "description": "Optional client-generated key that makes the POST safe to retry: a repeat with the same key and body replays the original response instead of creating a duplicate."
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CreateFunction"
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "The tool",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Function"
        }
       }
      }
     },
     "400": {
      "description": "Invalid request. `issues` names the offending field(s)."
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "404": {
      "description": "Not found, or not in the organization that owns the key."
     },
     "409": {
      "description": "Conflict \u2014 either the creation ceiling was reached for this organization (`agent_limit_reached`), or a request with the same Idempotency-Key is still in flight (`idempotency_in_progress`); retry the latter after the first attempt settles."
     },
     "422": {
      "description": "The Idempotency-Key was already used with a DIFFERENT request body (`idempotency_key_reused`). Reuse a key only to retry the identical request."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   }
  },
  "/api/v1/rules/{id}": {
   "get": {
    "summary": "Get one rule",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "agents:read",
    "x-rate-limit-per-minute": 120,
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      },
      "description": "The rule id."
     }
    ],
    "responses": {
     "200": {
      "description": "The rule",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Rule"
        }
       }
      }
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "404": {
      "description": "Not found, or not in the organization that owns the key."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   },
   "patch": {
    "summary": "Update a rule; activated:false retires it",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "agents:write",
    "x-rate-limit-per-minute": 30,
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      },
      "description": "The rule id."
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/UpdateRule"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The rule",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Rule"
        }
       }
      }
     },
     "400": {
      "description": "Invalid request. `issues` names the offending field(s)."
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "404": {
      "description": "Not found, or not in the organization that owns the key."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   }
  },
  "/api/v1/functions/{id}": {
   "get": {
    "summary": "Get one tool",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "agents:read",
    "x-rate-limit-per-minute": 120,
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      },
      "description": "The tool id."
     }
    ],
    "responses": {
     "200": {
      "description": "The tool",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Function"
        }
       }
      }
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "404": {
      "description": "Not found, or not in the organization that owns the key."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   },
   "patch": {
    "summary": "Update a tool; activated:false retires it",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "agents:write",
    "x-rate-limit-per-minute": 30,
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      },
      "description": "The tool id."
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/UpdateFunction"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "The tool",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Function"
        }
       }
      }
     },
     "400": {
      "description": "Invalid request. `issues` names the offending field(s)."
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "404": {
      "description": "Not found, or not in the organization that owns the key."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   }
  },
  "/api/v1/conversations": {
   "get": {
    "summary": "List recent customer conversations",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "responses:read",
    "x-rate-limit-per-minute": 120,
    "parameters": [
     {
      "name": "limit",
      "in": "query",
      "schema": {
       "type": "integer",
       "minimum": 1,
       "maximum": 100,
       "default": 25
      }
     },
     {
      "name": "offset",
      "in": "query",
      "schema": {
       "type": "integer",
       "minimum": 0,
       "default": 0
      }
     },
     {
      "name": "cursor",
      "in": "query",
      "schema": {
       "type": "string",
       "maxLength": 500
      },
      "description": "Opaque next_cursor from a previous page. Takes precedence over offset."
     },
     {
      "name": "status",
      "in": "query",
      "schema": {
       "type": "string",
       "maxLength": 80
      },
      "description": "Filter by status, e.g. open, closed, reviewed."
     },
     {
      "name": "channel",
      "in": "query",
      "schema": {
       "type": "string",
       "maxLength": 80
      },
      "description": "Filter by channel."
     },
     {
      "name": "agent_id",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "format": "uuid"
      },
      "description": "Filter to one agent."
     },
     {
      "name": "escalated",
      "in": "query",
      "schema": {
       "type": "string",
       "enum": [
        "true",
        "false"
       ]
      },
      "description": "Only escalated conversations."
     }
    ],
    "responses": {
     "200": {
      "description": "Conversations",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "object": {
           "type": "string",
           "enum": [
            "list"
           ]
          },
          "data": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/Conversation"
           }
          },
          "has_more": {
           "type": "boolean"
          },
          "next_cursor": {
           "type": "string",
           "description": "Keyset cursor for the next page \u2014 present only on cursor-capable lists with more rows."
          }
         }
        }
       }
      }
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   }
  },
  "/api/v1/conversations/{id}": {
   "get": {
    "summary": "Read one conversation with its message transcript",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "responses:read",
    "x-rate-limit-per-minute": 120,
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      },
      "description": "The conversation id."
     }
    ],
    "responses": {
     "200": {
      "description": "The conversation",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Conversation"
        }
       }
      }
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "404": {
      "description": "Not found, or not in the organization that owns the key."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   }
  },
  "/api/v1/responses": {
   "get": {
    "summary": "List handled response turns",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "responses:read",
    "x-rate-limit-per-minute": 120,
    "parameters": [
     {
      "name": "limit",
      "in": "query",
      "schema": {
       "type": "integer",
       "minimum": 1,
       "maximum": 100,
       "default": 25
      }
     },
     {
      "name": "offset",
      "in": "query",
      "schema": {
       "type": "integer",
       "minimum": 0,
       "default": 0
      }
     },
     {
      "name": "cursor",
      "in": "query",
      "schema": {
       "type": "string",
       "maxLength": 500
      },
      "description": "Opaque next_cursor from a previous page. Takes precedence over offset."
     },
     {
      "name": "channel",
      "in": "query",
      "schema": {
       "type": "string",
       "maxLength": 80
      },
      "description": "Filter by channel, e.g. email, chat."
     },
     {
      "name": "rating",
      "in": "query",
      "schema": {
       "type": "string",
       "maxLength": 80
      },
      "description": "Filter by rating value."
     },
     {
      "name": "escalated",
      "in": "query",
      "schema": {
       "type": "string",
       "enum": [
        "true",
        "false"
       ]
      },
      "description": "Only escalated (taken-over) responses."
     },
     {
      "name": "created_after",
      "in": "query",
      "schema": {
       "type": "string",
       "format": "date-time"
      }
     },
     {
      "name": "created_before",
      "in": "query",
      "schema": {
       "type": "string",
       "format": "date-time"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Responses",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "object": {
           "type": "string",
           "enum": [
            "list"
           ]
          },
          "data": {
           "type": "array",
           "items": {
            "$ref": "#/components/schemas/Response"
           }
          },
          "has_more": {
           "type": "boolean"
          },
          "next_cursor": {
           "type": "string",
           "description": "Keyset cursor for the next page \u2014 present only on cursor-capable lists with more rows."
          }
         }
        }
       }
      }
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   }
  },
  "/api/v1/responses/{id}": {
   "get": {
    "summary": "Get one response",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "responses:read",
    "x-rate-limit-per-minute": 120,
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      },
      "description": "The response id."
     }
    ],
    "responses": {
     "200": {
      "description": "The response",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Response"
        }
       }
      }
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "404": {
      "description": "Not found, or not in the organization that owns the key."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   }
  },
  "/api/v1/evals": {
   "get": {
    "summary": "List recorded evals (corrections made to agent replies)",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "responses:read",
    "x-rate-limit-per-minute": 120,
    "parameters": [
     {
      "name": "agent_id",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "format": "uuid"
      },
      "description": "Filter to one agent."
     },
     {
      "name": "response_id",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "format": "uuid"
      },
      "description": "Filter to one response."
     },
     {
      "name": "status",
      "in": "query",
      "schema": {
       "type": "string",
       "maxLength": 50
      },
      "description": "Filter by eval status."
     },
     {
      "name": "limit",
      "in": "query",
      "schema": {
       "type": "integer",
       "minimum": 1,
       "maximum": 100,
       "default": 25
      }
     },
     {
      "name": "offset",
      "in": "query",
      "schema": {
       "type": "integer",
       "minimum": 0,
       "default": 0
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Evals",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "object": {
           "type": "string",
           "enum": [
            "list"
           ]
          },
          "data": {
           "type": "array",
           "items": {
            "type": "object"
           }
          },
          "has_more": {
           "type": "boolean"
          },
          "next_cursor": {
           "type": "string",
           "description": "Keyset cursor for the next page \u2014 present only on cursor-capable lists with more rows."
          }
         }
        }
       }
      }
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   },
   "post": {
    "summary": "Record what the agent should have said",
    "description": "Stores a preference pair. When response_id is given, the customer message and the actual reply are read from the stored response rather than taken from the request, so the recorded pair is authentic.",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "responses:write",
    "x-rate-limit-per-minute": 30,
    "parameters": [
     {
      "name": "Idempotency-Key",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string",
       "maxLength": 200
      },
      "description": "Optional client-generated key that makes the POST safe to retry: a repeat with the same key and body replays the original response instead of creating a duplicate."
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CreateEval"
       }
      }
     }
    },
    "responses": {
     "201": {
      "description": "The eval",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "400": {
      "description": "Invalid request. `issues` names the offending field(s)."
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "404": {
      "description": "Not found, or not in the organization that owns the key."
     },
     "409": {
      "description": "Conflict \u2014 either the creation ceiling was reached for this organization (`agent_limit_reached`), or a request with the same Idempotency-Key is still in flight (`idempotency_in_progress`); retry the latter after the first attempt settles."
     },
     "422": {
      "description": "The Idempotency-Key was already used with a DIFFERENT request body (`idempotency_key_reused`). Reuse a key only to retry the identical request."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   }
  },
  "/api/v1/evals/{id}": {
   "get": {
    "summary": "Get one eval",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "responses:read",
    "x-rate-limit-per-minute": 120,
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      },
      "description": "The eval id."
     }
    ],
    "responses": {
     "200": {
      "description": "The eval",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "404": {
      "description": "Not found, or not in the organization that owns the key."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   }
  },
  "/api/v1/evals/{id}/run": {
   "post": {
    "summary": "Replay one eval and grade it against the recorded answer",
    "description": "Runs the real generation path, then grades the reply against preferred_output on substance rather than wording. `passed` is null \u2014 never false \u2014 when grading could not run, so an unavailable judge is not mistaken for a failing agent.",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "responses:write",
    "x-rate-limit-per-minute": 30,
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      },
      "description": "The eval id."
     }
    ],
    "responses": {
     "200": {
      "description": "The run result",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "400": {
      "description": "Invalid request. `issues` names the offending field(s)."
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "404": {
      "description": "Not found, or not in the organization that owns the key."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   }
  },
  "/api/v1/agents/{id}/evals/run": {
   "post": {
    "summary": "Run an agent's eval suite (regression check)",
    "description": "Each eval costs a real generation plus a judge call, so runs are sequential and capped per call; has_more reports when the suite was longer than the cap.",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "responses:write",
    "x-rate-limit-per-minute": 30,
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      },
      "description": "The agent id."
     }
    ],
    "responses": {
     "200": {
      "description": "Suite result",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "400": {
      "description": "Invalid request. `issues` names the offending field(s)."
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "404": {
      "description": "Not found, or not in the organization that owns the key."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   }
  },
  "/api/v1/integrations": {
   "get": {
    "summary": "Shopify and Gorgias connection status (identifiers, never tokens)",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "agents:read",
    "x-rate-limit-per-minute": 120,
    "responses": {
     "200": {
      "description": "Integration status",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   }
  },
  "/api/v1/integrations/shopify": {
   "post": {
    "summary": "Connect Shopify with a custom-app Admin API token",
    "description": "The token is verified against the store live before it is stored, and is never returned by any read. Replacing an existing connection requires confirm_replace. For browser OAuth instead, use the connect_url from the status endpoint.",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "agents:write",
    "x-rate-limit-per-minute": 30,
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ConnectShopify"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Connection result",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "400": {
      "description": "Invalid request. `issues` names the offending field(s)."
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "409": {
      "description": "Conflict \u2014 either the creation ceiling was reached for this organization (`agent_limit_reached`), or a request with the same Idempotency-Key is still in flight (`idempotency_in_progress`); retry the latter after the first attempt settles."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   }
  },
  "/api/v1/integrations/gorgias": {
   "post": {
    "summary": "Connect Gorgias with an agent email + REST API key",
    "description": "Credentials are verified against Gorgias live before storage. Replacing an existing connection requires confirm_replace.",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "agents:write",
    "x-rate-limit-per-minute": 30,
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/ConnectGorgias"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Connection result",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "400": {
      "description": "Invalid request. `issues` names the offending field(s)."
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "409": {
      "description": "Conflict \u2014 either the creation ceiling was reached for this organization (`agent_limit_reached`), or a request with the same Idempotency-Key is still in flight (`idempotency_in_progress`); retry the latter after the first attempt settles."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   }
  },
  "/api/v1/integrations/shopify/import-knowledge": {
   "post": {
    "summary": "Ground agents from the store: import products, collections and policies",
    "description": "Near-duplicates update in place, so re-running refreshes rather than duplicates.",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "knowledge:write",
    "x-rate-limit-per-minute": 30,
    "responses": {
     "200": {
      "description": "Import result",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "400": {
      "description": "Invalid request. `issues` names the offending field(s)."
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   }
  },
  "/api/v1/analytics/summary": {
   "get": {
    "summary": "Total, AI-handled and human-handled counts over a window",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "analytics:read",
    "x-rate-limit-per-minute": 120,
    "parameters": [
     {
      "name": "days",
      "in": "query",
      "schema": {
       "type": "integer",
       "minimum": 1,
       "maximum": 365,
       "default": 30
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Summary",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   }
  },
  "/api/v1/analytics/agents": {
   "get": {
    "summary": "Per-agent volume, AI vs human handling, and human-handled rate",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "analytics:read",
    "x-rate-limit-per-minute": 120,
    "parameters": [
     {
      "name": "days",
      "in": "query",
      "schema": {
       "type": "integer",
       "minimum": 1,
       "maximum": 365,
       "default": 30
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Per-agent analytics",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   }
  },
  "/api/v1/changes": {
   "get": {
    "summary": "Configuration change log for agents, rules and tools",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "agents:read",
    "x-rate-limit-per-minute": 120,
    "parameters": [
     {
      "name": "limit",
      "in": "query",
      "schema": {
       "type": "integer",
       "minimum": 1,
       "maximum": 100,
       "default": 25
      }
     },
     {
      "name": "offset",
      "in": "query",
      "schema": {
       "type": "integer",
       "minimum": 0,
       "default": 0
      }
     },
     {
      "name": "resource_id",
      "in": "query",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Changes",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "object": {
           "type": "string",
           "enum": [
            "list"
           ]
          },
          "data": {
           "type": "array",
           "items": {
            "type": "object"
           }
          },
          "has_more": {
           "type": "boolean"
          },
          "next_cursor": {
           "type": "string",
           "description": "Keyset cursor for the next page \u2014 present only on cursor-capable lists with more rows."
          }
         }
        }
       }
      }
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   }
  },
  "/api/v1/functions/{id}/test": {
   "post": {
    "summary": "Probe a tool's endpoint and report whether it works",
    "description": "A broken tool fails silently during a conversation. Non-safe methods are probed with OPTIONS so the probe cannot cause a side effect.",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "agents:read",
    "x-rate-limit-per-minute": 10,
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      },
      "description": "The tool id."
     }
    ],
    "responses": {
     "200": {
      "description": "Probe result",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "404": {
      "description": "Not found, or not in the organization that owns the key."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   }
  },
  "/api/v1/knowledge": {
   "get": {
    "summary": "List stored knowledge documents",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "knowledge:read",
    "x-rate-limit-per-minute": 120,
    "parameters": [
     {
      "name": "limit",
      "in": "query",
      "schema": {
       "type": "integer",
       "minimum": 1,
       "maximum": 100,
       "default": 25
      }
     },
     {
      "name": "cursor",
      "in": "query",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Knowledge documents. Alongside the list envelope, `next_cursor` carries the opaque cursor for the next page (pass it back as `cursor`); it is null on the last page.",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "object": {
           "type": "string",
           "enum": [
            "list"
           ]
          },
          "data": {
           "type": "array",
           "items": {
            "type": "object"
           }
          },
          "has_more": {
           "type": "boolean"
          },
          "next_cursor": {
           "type": "string",
           "description": "Keyset cursor for the next page \u2014 present only on cursor-capable lists with more rows."
          }
         }
        }
       }
      }
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   },
   "post": {
    "summary": "Add a knowledge-base document (near-duplicates update in place)",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "knowledge:write",
    "x-rate-limit-per-minute": 10,
    "parameters": [
     {
      "name": "Idempotency-Key",
      "in": "header",
      "required": false,
      "schema": {
       "type": "string",
       "maxLength": 200
      },
      "description": "Optional client-generated key that makes the POST safe to retry: a repeat with the same key and body replays the original response instead of creating a duplicate."
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "required": [
         "knowledge"
        ],
        "properties": {
         "knowledge": {
          "type": "string",
          "maxLength": 100000
         },
         "metadata": {
          "type": "object"
         },
         "force_create": {
          "type": "boolean"
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Write result",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "400": {
      "description": "Invalid request. `issues` names the offending field(s)."
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "409": {
      "description": "Conflict \u2014 either the creation ceiling was reached for this organization (`agent_limit_reached`), or a request with the same Idempotency-Key is still in flight (`idempotency_in_progress`); retry the latter after the first attempt settles."
     },
     "422": {
      "description": "The Idempotency-Key was already used with a DIFFERENT request body (`idempotency_key_reused`). Reuse a key only to retry the identical request."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   }
  },
  "/api/v1/knowledge/{id}": {
   "delete": {
    "summary": "Remove an obsolete knowledge document (not reversible)",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "knowledge:write",
    "x-rate-limit-per-minute": 30,
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Delete result",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "404": {
      "description": "Not found, or not in the organization that owns the key."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   },
   "patch": {
    "summary": "Correct a knowledge document in place",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "knowledge:write",
    "x-rate-limit-per-minute": 10,
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "required": [
         "knowledge"
        ],
        "properties": {
         "knowledge": {
          "type": "string",
          "maxLength": 100000
         },
         "metadata": {
          "type": "object"
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Write result",
      "content": {
       "application/json": {
        "schema": {
         "type": "object"
        }
       }
      }
     },
     "400": {
      "description": "Invalid request. `issues` names the offending field(s)."
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "404": {
      "description": "Not found, or not in the organization that owns the key."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   }
  },
  "/api/v1/knowledge/search": {
   "post": {
    "summary": "Semantic search over the knowledge base",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "x-required-scope": "knowledge:read",
    "x-rate-limit-per-minute": 10,
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "required": [
         "question"
        ],
        "properties": {
         "question": {
          "type": "string",
          "maxLength": 10000
         },
         "top_k": {
          "type": "integer",
          "minimum": 1,
          "maximum": 100,
          "default": 5
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Matches",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "object": {
           "type": "string",
           "enum": [
            "list"
           ]
          },
          "data": {
           "type": "array",
           "items": {
            "type": "object"
           }
          },
          "has_more": {
           "type": "boolean"
          },
          "next_cursor": {
           "type": "string",
           "description": "Keyset cursor for the next page \u2014 present only on cursor-capable lists with more rows."
          }
         }
        }
       }
      }
     },
     "400": {
      "description": "Invalid request. `issues` names the offending field(s)."
     },
     "401": {
      "description": "Missing, invalid, or expired API key."
     },
     "403": {
      "description": "The key lacks a required scope."
     },
     "429": {
      "description": "Rate limit exceeded."
     }
    }
   }
  }
 }
}