{
  "openapi": "3.0.3",
  "info": {
    "title": "ISMS Copilot Model API",
    "version": "1.0.0",
    "license": {
      "name": "Proprietary",
      "url": "https://www.ismscopilot.com"
    },
    "description": "Compliance model API. OpenAI-compatible chat completions where the product is framework knowledge: curated compliance modules from a maintained registry (ISO 27001, SOC 2, GDPR, NIS 2, DORA, HIPAA, NIST families, and more; the public catalog endpoint is the source of truth) are selected per request and injected into the prompt before generation. Every successful completion discloses which modules were injected.\n\nKey facts:\n- Wire: an OpenAI chat completions subset. Text-only: tool and function definitions, JSON mode, logprobs, n above 1, and multimodal parts are rejected with 400. Streaming (SSE) is supported.\n- Grounding controls: ismscopilot.frameworks = \"auto\" (default; detects named frameworks in user messages and the last assistant turn), \"none\", or a pinned list of up to 8 catalog ids. Detection does not scan system or developer messages.\n- Aliases: isms-fast, isms-thinking, plus isms-fast-eu and isms-thinking-eu for the EU processing path (Mistral under EU data-protection terms). isms-mini is the low-cost bulk lane (formatting, extraction, classification) on a smaller model, on the global path, no thinking mode. The processing region is returned in the x-isms-processing-region response header.\n- Auth: Bearer sk-isms keys, created in the developer console at platform.ismscopilot.com. Prepaid credits, separate from any chat subscription; optional per-key spend caps. Unit rates are listed in the console, which is the source of truth for pricing.\n- Data handling: request content (prompts, outputs) is not stored as customer records; usage metadata only. Upstream providers on both paths are configured for zero retention of request content.\n- Docs: https://docs.ismscopilot.com/docs/api",
    "contact": {
      "name": "ISMS Copilot support",
      "url": "https://docs.ismscopilot.com"
    }
  },
  "servers": [
    {
      "url": "https://api.ismscopilot.com/v1",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "completions",
      "description": "Chat completions with framework knowledge injection"
    },
    {
      "name": "models",
      "description": "Model alias listing"
    },
    {
      "name": "frameworks",
      "description": "Public catalog of injectable framework knowledge modules"
    }
  ],
  "paths": {
    "/chat/completions": {
      "post": {
        "tags": [
          "completions"
        ],
        "summary": "Create a chat completion",
        "description": "OpenAI-compatible chat completions. The server detects or pins framework knowledge modules, injects them into the prompt before generation, and discloses which modules ran on successful completions in the response headers and body. Requires a positive prepaid credit balance. Text-only subset: requests containing tool or function definitions, JSON mode (response_format other than text), logprobs, n above 1, or multimodal content parts are rejected with 400. Requests whose assembled prompt would exceed the context window are rejected locally with error code context_length_exceeded before billing. Request bodies larger than 10 MiB are rejected with 413 and code request_too_large. When stream is true, the response is an SSE text/event-stream; each data frame carries a JSON object of the chat.completion.chunk shape (see the ChatCompletionStreamResponse schema).",
        "operationId": "createChatCompletion",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateChatCompletionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful completion (or SSE stream when stream is true)",
            "headers": {
              "x-isms-frameworks": {
                "description": "Comma-separated catalog ids of the framework modules injected into this request (empty when none)",
                "schema": {
                  "type": "string",
                  "example": "ISO_27001"
                }
              },
              "x-isms-policy-version": {
                "description": "Version identifier of the server prompt policy applied to this request",
                "schema": {
                  "type": "string",
                  "example": "server-prompt-v1"
                }
              },
              "x-isms-policy-applied": {
                "description": "Whether the published server prompt was applied",
                "schema": {
                  "type": "boolean"
                }
              },
              "x-isms-processing-region": {
                "description": "Processing path used for this request",
                "schema": {
                  "type": "string",
                  "enum": [
                    "global",
                    "eu"
                  ]
                }
              },
              "x-isms-max-tokens-requested": {
                "description": "The max_tokens value the client requested (present when a floor was applied)",
                "schema": {
                  "type": "integer"
                }
              },
              "x-isms-max-tokens-effective": {
                "description": "The max_tokens value actually used. Thinking aliases floor max_tokens at 1024 when a lower value is requested",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChatCompletionResponse"
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string"
                },
                "example": "data: {\"id\":\"chatcmpl-...\",\"object\":\"chat.completion.chunk\",\"created\":1787683890,\"model\":\"isms-fast\",\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"\"},\"finish_reason\":null}]}\n\ndata: {\"object\":\"chat.completion.chunk\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\"A.5.10\"},\"finish_reason\":null}]}\n\ndata: {\"object\":\"chat.completion.chunk\",\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}]}\n\ndata: [DONE]\n\n"
              }
            }
          },
          "400": {
            "description": "Invalid request. Includes unsupported parameters (tools, functions, logprobs, n above 1, response_format other than text, multimodal parts), invalid ismscopilot extension values (more than 8 pinned ids, unknown ids), the extension being disabled for the key (code ismscopilot_extension_disabled), and prompt assembly exceeding the context window (code context_length_exceeded, rejected locally before billing)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown model alias (code model_not_found)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "Request body larger than 10 MiB (code request_too_large)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Quota exceeded. Code insufficient_quota when the prepaid balance is empty or not positive; codes hour_limit_exceeded, day_limit_exceeded, week_limit_exceeded, or month_limit_exceeded when a per-key spend cap is configured and exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/models": {
      "get": {
        "tags": [
          "models"
        ],
        "summary": "List model aliases",
        "description": "Lists the model aliases available on this API. Authentication is required; no credit balance is needed.",
        "operationId": "listModels",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Model list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModelList"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/models/{model}": {
      "get": {
        "tags": [
          "models"
        ],
        "summary": "Retrieve a model alias",
        "operationId": "retrieveModel",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "model",
            "in": "path",
            "required": true,
            "description": "Model alias id",
            "schema": {
              "type": "string"
            },
            "example": "isms-fast"
          }
        ],
        "responses": {
          "200": {
            "description": "Model object",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Model"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Unknown model alias (code model_not_found)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/frameworks": {
      "get": {
        "tags": [
          "frameworks"
        ],
        "summary": "List framework knowledge modules",
        "description": "The public catalog of injectable framework knowledge modules. No authentication required. The count field is generated from the same registry the API injects from; treat this endpoint as the source of truth for coverage. Module ids are the valid values for the ismscopilot.frameworks pin list on chat completions.",
        "operationId": "listFrameworks",
        "security": [],
        "responses": {
          "200": {
            "description": "Framework catalog",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FrameworkList"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key with the sk-isms- prefix, created at https://platform.ismscopilot.com/keys. Send as: Authorization: Bearer sk-isms-..."
      }
    },
    "schemas": {
      "CreateChatCompletionRequest": {
        "type": "object",
        "required": [
          "model",
          "messages"
        ],
        "properties": {
          "model": {
            "type": "string",
            "enum": [
              "isms-fast",
              "isms-thinking",
              "isms-fast-eu",
              "isms-thinking-eu",
              "isms-mini"
            ],
            "description": "Model alias. isms-fast and isms-thinking use the global path; the -eu twins use the EU processing path"
          },
          "messages": {
            "type": "array",
            "minItems": 1,
            "items": {
              "$ref": "#/components/schemas/ChatMessage"
            }
          },
          "temperature": {
            "type": "number",
            "description": "Sampling temperature"
          },
          "top_p": {
            "type": "number",
            "description": "Nucleus sampling parameter"
          },
          "max_tokens": {
            "type": "integer",
            "description": "Upper bound on generated tokens. Thinking aliases apply a floor of 1024 when a lower value is sent; requested vs effective values are returned in response headers"
          },
          "max_completion_tokens": {
            "type": "integer",
            "description": "Alias of max_tokens, accepted like the OpenAI API accepts it"
          },
          "stop": {
            "description": "Stop sequences",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            ]
          },
          "stream": {
            "type": "boolean",
            "default": false,
            "description": "When true, the response is an SSE stream of chat.completion.chunk objects ending with data: [DONE]"
          },
          "stream_options": {
            "type": "object",
            "properties": {
              "include_usage": {
                "type": "boolean",
                "description": "Include a final usage chunk before [DONE] when streaming"
              }
            }
          },
          "ismscopilot": {
            "allOf": [
              {
                "$ref": "#/components/schemas/IsmscopilotExtension"
              }
            ],
            "description": "ISMS Copilot extension controls for framework knowledge and the server prompt"
          }
        },
        "description": "Documented OpenAI-compatible subset. Not supported and rejected with 400: tools, function_call, logprobs, n above 1, response_format other than text, and multimodal content parts"
      },
      "IsmscopilotExtension": {
        "type": "object",
        "properties": {
          "system": {
            "type": "string",
            "enum": [
              "v1",
              "none"
            ],
            "default": "v1",
            "description": "v1 (default) applies the published compliance server prompt. none removes it atomically; framework injection still follows the frameworks setting"
          },
          "frameworks": {
            "description": "auto (default) detects named frameworks in user messages and the last assistant turn; none injects nothing and no knowledge tokens are billed; a pinned list always injects exactly those catalog ids (max 8), ordered by registry order",
            "oneOf": [
              {
                "type": "string",
                "enum": [
                  "auto",
                  "none"
                ]
              },
              {
                "type": "array",
                "maxItems": 8,
                "items": {
                  "type": "string"
                },
                "example": [
                  "ISO_27001",
                  "SOC_2"
                ]
              }
            ],
            "default": "auto"
          }
        }
      },
      "ChatMessage": {
        "type": "object",
        "required": [
          "role",
          "content"
        ],
        "properties": {
          "role": {
            "type": "string",
            "enum": [
              "system",
              "developer",
              "user",
              "assistant"
            ]
          },
          "content": {
            "description": "Text content, as a plain string or an array of text parts",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "type",
                    "text"
                  ],
                  "properties": {
                    "type": {
                      "type": "string",
                      "enum": [
                        "text"
                      ]
                    },
                    "text": {
                      "type": "string"
                    }
                  }
                }
              }
            ]
          }
        }
      },
      "ChatCompletionResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "chatcmpl-1c6dabaebb744de9aca0fc8bd48f49ae"
          },
          "object": {
            "type": "string",
            "enum": [
              "chat.completion"
            ]
          },
          "created": {
            "type": "integer",
            "description": "Unix timestamp (seconds)"
          },
          "model": {
            "type": "string",
            "description": "The alias requested; the underlying provider model is not exposed",
            "example": "isms-fast"
          },
          "choices": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "index": {
                  "type": "integer"
                },
                "message": {
                  "type": "object",
                  "properties": {
                    "role": {
                      "type": "string",
                      "enum": [
                        "assistant"
                      ]
                    },
                    "content": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                },
                "finish_reason": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "index",
                "message",
                "finish_reason"
              ]
            }
          },
          "usage": {
            "type": "object",
            "description": "Token usage. Everything the server adds to the prompt, including injected framework knowledge, is billed as input tokens",
            "properties": {
              "prompt_tokens": {
                "type": "integer"
              },
              "completion_tokens": {
                "type": "integer"
              },
              "total_tokens": {
                "type": "integer"
              }
            },
            "required": [
              "prompt_tokens",
              "completion_tokens",
              "total_tokens"
            ]
          },
          "service_tier": {
            "type": "string",
            "nullable": true
          },
          "ismscopilot": {
            "$ref": "#/components/schemas/IsmcopilotDisclosure"
          }
        },
        "required": [
          "id",
          "object",
          "created",
          "model",
          "choices",
          "usage"
        ]
      },
      "IsmcopilotDisclosure": {
        "type": "object",
        "description": "Disclosure object present when extensions are active: which framework modules grounded this completion and the estimated size of the injected knowledge",
        "properties": {
          "frameworks": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "ISO_27001"
            ]
          },
          "knowledge_characters": {
            "type": "integer",
            "example": 8992
          },
          "knowledge_tokens": {
            "type": "integer",
            "example": 2998
          },
          "knowledge_tokens_method": {
            "type": "string",
            "example": "chars_div_3_v1"
          }
        },
        "required": [
          "frameworks",
          "knowledge_characters",
          "knowledge_tokens",
          "knowledge_tokens_method"
        ]
      },
      "ChatCompletionStreamResponse": {
        "type": "object",
        "description": "Payload of each SSE data frame on the stream (the stream itself is text/event-stream). Events: a role prelude chunk, content delta chunks, a terminal chunk carrying finish_reason and the ismscopilot disclosure, an optional usage chunk (when stream_options.include_usage is true), then data: [DONE]. Mid-stream provider failures surface as an OpenAI-style error event without [DONE]",
        "properties": {
          "id": {
            "type": "string"
          },
          "object": {
            "type": "string",
            "enum": [
              "chat.completion.chunk"
            ]
          },
          "created": {
            "type": "integer"
          },
          "model": {
            "type": "string"
          },
          "choices": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "index": {
                  "type": "integer"
                },
                "delta": {
                  "type": "object",
                  "properties": {
                    "role": {
                      "type": "string"
                    },
                    "content": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                },
                "finish_reason": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "index",
                "delta",
                "finish_reason"
              ]
            }
          },
          "usage": {
            "type": "object",
            "description": "Present on the final usage chunk when stream_options.include_usage is true",
            "properties": {
              "prompt_tokens": {
                "type": "integer"
              },
              "completion_tokens": {
                "type": "integer"
              },
              "total_tokens": {
                "type": "integer"
              }
            }
          },
          "ismscopilot": {
            "$ref": "#/components/schemas/IsmcopilotDisclosure"
          }
        },
        "required": [
          "id",
          "object",
          "created",
          "model",
          "choices"
        ]
      },
      "Model": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "isms-fast"
          },
          "object": {
            "type": "string",
            "enum": [
              "model"
            ]
          },
          "created": {
            "type": "integer"
          },
          "owned_by": {
            "type": "string",
            "example": "ismscopilot"
          }
        },
        "required": [
          "id",
          "object",
          "created",
          "owned_by"
        ]
      },
      "ModelList": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "enum": [
              "list"
            ]
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Model"
            }
          }
        },
        "required": [
          "object",
          "data"
        ]
      },
      "Framework": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Catalog id, valid in the ismscopilot.frameworks pin list",
            "example": "ISO_27001"
          },
          "name": {
            "type": "string",
            "example": "ISO/IEC 27001:2022"
          },
          "region": {
            "type": "string",
            "example": "International"
          },
          "version": {
            "type": "string",
            "example": "2022"
          },
          "deprecated": {
            "type": "boolean"
          },
          "replacement_id": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "id",
          "name",
          "region",
          "version",
          "deprecated",
          "replacement_id"
        ]
      },
      "FrameworkList": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "enum": [
              "list"
            ]
          },
          "schema_version": {
            "type": "integer",
            "example": 1
          },
          "count": {
            "type": "integer",
            "description": "Number of modules in the registry; generated from the same registry the API injects from",
            "example": 101
          },
          "registry_hash": {
            "type": "string",
            "description": "Hash of the registry content, changes when modules ship"
          },
          "release": {
            "type": "string",
            "description": "Serving release identifier"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Framework"
            }
          }
        },
        "required": [
          "object",
          "schema_version",
          "count",
          "registry_hash",
          "release",
          "data"
        ]
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "message": {
                "type": "string"
              },
              "type": {
                "type": "string",
                "nullable": true
              },
              "param": {
                "type": "string",
                "nullable": true
              },
              "code": {
                "type": "string",
                "nullable": true,
                "description": "Examples: model_not_found, insufficient_quota, context_length_exceeded, request_too_large, ismscopilot_extension_disabled, hour_limit_exceeded, day_limit_exceeded, week_limit_exceeded, month_limit_exceeded"
              }
            },
            "required": [
              "message"
            ]
          }
        },
        "required": [
          "error"
        ]
      }
    }
  },
  "externalDocs": {
    "description": "ISMS Copilot Model API documentation",
    "url": "https://docs.ismscopilot.com/docs/api"
  }
}
