{
  "openapi": "3.1.0",
  "info": {
    "title": "eu/jev API",
    "version": "eu-jeff-1.0.0",
    "summary": "System One inference hosted in Germany.",
    "description": "One endpoint turns context into choices, probabilities, and scores. Requests follow TypeSafe's System One HTTP payload structure; set `model` to `eu-jeff-latest`. Pricing: €37 per billion input tokens, output tokens are free. Prompts and responses are processed on our server in Germany and are not stored.",
    "contact": {
      "email": "juan@bevel.software",
      "url": "https://eu-jev.com/docs"
    },
    "termsOfService": "https://eu-jev.com/terms"
  },
  "servers": [
    {
      "url": "https://eu-jev.com"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/v1/systemone": {
      "post": {
        "operationId": "decide",
        "summary": "Answer one or more typed questions about a state",
        "description": "Sends the state and up to eight named questions to the model. Each question is a choice (2-64 options), a noul (yes/no probability), or a score (ordered scale of 2-10 levels). Failed requests are not charged. Limits: 256 KiB JSON body, 100,000 characters for a string state, 1,000 characters per instruction and 500 per criterion after serialization, 60 requests per minute per account.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DecisionRequest"
              },
              "example": {
                "model": "eu-jeff-latest",
                "state": "I was charged twice. Can I get a refund?",
                "questions": {
                  "team": {
                    "type": "choice",
                    "instructions": "Which team should handle this?",
                    "criteria": {
                      "billing": "Payments, invoices, and refunds",
                      "support": "Technical issues and bugs"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Structured answers, one per question.",
            "headers": {
              "X-Request-ID": {
                "description": "Matches meta.request_id; quote it to support.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DecisionResponse"
                },
                "example": {
                  "model": "eu-jeff-1.0.0",
                  "answers": {
                    "team": {
                      "type": "choice",
                      "choice": "billing",
                      "confidence": 0.9,
                      "probabilities": {
                        "billing": 0.95,
                        "support": 0.05
                      }
                    }
                  },
                  "usage": {
                    "input_tokens": 64,
                    "output_tokens": 0
                  },
                  "meta": {
                    "request_id": "8febf2e9-1643-4446-a7cf-7fc3bcf2b391",
                    "mode": "live",
                    "latency_ms": 180,
                    "cost_eur": "0.000002368"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input, including an unknown model ID such as a Jev model ID.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid, or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account balance cannot cover this request. The body includes code and contact_url.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "The JSON body exceeds 256 KiB.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "415": {
            "description": "The Content-Type is not application/json.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "The model cannot process this input, for example because it exceeds the 32,768-position context allocation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited. Wait for the Retry-After header, in seconds.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "The model is busy, starting, or unavailable. Retry with backoff and respect Retry-After.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "An API key from the eu/jev dashboard."
      }
    },
    "schemas": {
      "DecisionRequest": {
        "type": "object",
        "required": [
          "state",
          "questions"
        ],
        "properties": {
          "model": {
            "type": "string",
            "enum": [
              "eu-jeff-latest",
              "eu-jeff-1.0.0"
            ],
            "default": "eu-jeff-latest",
            "description": "eu-jeff-latest follows the current release; eu-jeff-1.0.0 pins it. Jev model IDs are rejected."
          },
          "state": {
            "description": "The content to evaluate: a string of up to 100,000 characters, or a JSON object or array.",
            "oneOf": [
              {
                "type": "string",
                "minLength": 1,
                "maxLength": 100000
              },
              {
                "type": "object"
              },
              {
                "type": "array"
              }
            ]
          },
          "questions": {
            "type": "object",
            "description": "One to eight questions, keyed by names of up to 80 characters.",
            "minProperties": 1,
            "maxProperties": 8,
            "additionalProperties": {
              "$ref": "#/components/schemas/Question"
            }
          }
        }
      },
      "Question": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/ChoiceQuestion"
          },
          {
            "$ref": "#/components/schemas/NoulQuestion"
          },
          {
            "$ref": "#/components/schemas/ScoreQuestion"
          }
        ],
        "discriminator": {
          "propertyName": "type",
          "mapping": {
            "choice": "#/components/schemas/ChoiceQuestion",
            "noul": "#/components/schemas/NoulQuestion",
            "score": "#/components/schemas/ScoreQuestion"
          }
        }
      },
      "ChoiceQuestion": {
        "type": "object",
        "required": [
          "type",
          "instructions",
          "criteria"
        ],
        "properties": {
          "type": {
            "type": "string",
            "const": "choice"
          },
          "instructions": {
            "description": "Free text, or a JSON object, array, or null that is serialized to text before inference.",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "object"
              },
              {
                "type": "array"
              },
              {
                "type": "null"
              }
            ]
          },
          "criteria": {
            "type": "object",
            "description": "Two to 64 options: option name to description. A null description uses the option name.",
            "minProperties": 2,
            "maxProperties": 64,
            "additionalProperties": {
              "description": "Free text, or a JSON object, array, or null that is serialized to text before inference.",
              "oneOf": [
                {
                  "type": "string"
                },
                {
                  "type": "object"
                },
                {
                  "type": "array"
                },
                {
                  "type": "null"
                }
              ]
            }
          }
        }
      },
      "NoulQuestion": {
        "type": "object",
        "required": [
          "type",
          "instructions"
        ],
        "properties": {
          "type": {
            "type": "string",
            "const": "noul"
          },
          "instructions": {
            "description": "Free text, or a JSON object, array, or null that is serialized to text before inference.",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "object"
              },
              {
                "type": "array"
              },
              {
                "type": "null"
              }
            ]
          },
          "criteria": {
            "type": "object",
            "description": "Optional descriptions of what true and false mean.",
            "properties": {
              "true": {
                "description": "Free text, or a JSON object, array, or null that is serialized to text before inference.",
                "oneOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "object"
                  },
                  {
                    "type": "array"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "false": {
                "description": "Free text, or a JSON object, array, or null that is serialized to text before inference.",
                "oneOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "object"
                  },
                  {
                    "type": "array"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            }
          }
        }
      },
      "ScoreQuestion": {
        "type": "object",
        "required": [
          "type",
          "instructions",
          "criteria"
        ],
        "properties": {
          "type": {
            "type": "string",
            "const": "score"
          },
          "instructions": {
            "description": "Free text, or a JSON object, array, or null that is serialized to text before inference.",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "object"
              },
              {
                "type": "array"
              },
              {
                "type": "null"
              }
            ]
          },
          "criteria": {
            "type": "array",
            "description": "Two to 10 level descriptions, ordered from low to high.",
            "minItems": 2,
            "maxItems": 10,
            "items": {
              "description": "Free text, or a JSON object, array, or null that is serialized to text before inference.",
              "oneOf": [
                {
                  "type": "string"
                },
                {
                  "type": "object"
                },
                {
                  "type": "array"
                },
                {
                  "type": "null"
                }
              ]
            }
          }
        }
      },
      "DecisionResponse": {
        "type": "object",
        "required": [
          "model",
          "answers",
          "usage",
          "meta"
        ],
        "properties": {
          "model": {
            "type": "string",
            "description": "The release that answered, for example eu-jeff-1.0.0."
          },
          "answers": {
            "type": "object",
            "description": "One answer per question, under the same names.",
            "additionalProperties": {
              "$ref": "#/components/schemas/Answer"
            }
          },
          "usage": {
            "type": "object",
            "required": [
              "input_tokens",
              "output_tokens"
            ],
            "properties": {
              "input_tokens": {
                "type": "integer",
                "minimum": 0
              },
              "output_tokens": {
                "type": "integer",
                "minimum": 0
              }
            }
          },
          "meta": {
            "type": "object",
            "required": [
              "request_id",
              "mode",
              "latency_ms"
            ],
            "properties": {
              "request_id": {
                "type": "string"
              },
              "mode": {
                "type": "string",
                "const": "live"
              },
              "latency_ms": {
                "type": "integer",
                "description": "Server-side time for token quoting, credit reservation, and inference."
              },
              "cost_eur": {
                "type": "string",
                "description": "The exact charge in euros, on authenticated requests."
              }
            }
          }
        }
      },
      "Answer": {
        "oneOf": [
          {
            "type": "object",
            "required": [
              "type",
              "choice",
              "confidence",
              "probabilities"
            ],
            "properties": {
              "type": {
                "type": "string",
                "const": "choice"
              },
              "choice": {
                "type": "string"
              },
              "confidence": {
                "type": "number",
                "minimum": 0,
                "maximum": 1,
                "description": "Normalized inverse entropy of the probabilities, 1 − H(p) / ln(n) for n options: 1 when one option holds all probability, 0 when all are equally likely."
              },
              "probabilities": {
                "type": "object",
                "additionalProperties": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 1
                }
              }
            }
          },
          {
            "type": "object",
            "required": [
              "type",
              "noul"
            ],
            "properties": {
              "type": {
                "type": "string",
                "const": "noul"
              },
              "noul": {
                "type": "number",
                "minimum": 0,
                "maximum": 1,
                "description": "The probability that the condition is true."
              }
            }
          },
          {
            "type": "object",
            "required": [
              "type",
              "score",
              "confidence",
              "probabilities",
              "legend"
            ],
            "properties": {
              "type": {
                "type": "string",
                "const": "score"
              },
              "score": {
                "type": "number",
                "description": "The expected position on the scale, from 0 to N−1."
              },
              "confidence": {
                "type": "number",
                "minimum": 0,
                "maximum": 1
              },
              "probabilities": {
                "type": "object",
                "additionalProperties": {
                  "type": "number",
                  "minimum": 0,
                  "maximum": 1
                }
              },
              "legend": {
                "type": "object",
                "description": "Position to level description.",
                "additionalProperties": {
                  "type": "string"
                }
              }
            }
          }
        ]
      },
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string",
            "description": "A human-readable message."
          },
          "code": {
            "type": "string",
            "description": "Present on some errors, for example insufficient_credits or rate_limited."
          },
          "contact_url": {
            "type": "string",
            "description": "Where to request extra usage, on 402 responses."
          }
        }
      }
    }
  }
}
