{
  "components": {
    "schemas": {
      "AgeBand": {
        "enum": [
          "Age13To15",
          "Age16To17",
          "Adult"
        ]
      },
      "PartnerLearnerRequest": {
        "additionalProperties": false,
        "properties": {
          "ageBand": {
            "$ref": "#/components/schemas/AgeBand"
          },
          "displayName": {
            "type": [
              "null",
              "string"
            ]
          },
          "locale": {
            "type": [
              "null",
              "string"
            ]
          }
        },
        "required": [
          "ageBand"
        ],
        "type": "object"
      },
      "PartnerProblem": {
        "properties": {
          "clientTurnId": {
            "format": "uuid",
            "type": "string"
          },
          "detail": {
            "type": "string"
          },
          "errors": {
            "items": {
              "properties": {
                "code": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              },
              "type": "object"
            },
            "type": "array"
          },
          "instance": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "title": {
            "type": "string"
          },
          "traceId": {
            "type": "string"
          },
          "type": {
            "type": "string"
          }
        },
        "type": "object"
      },
      "PartnerSessionResponse": {
        "properties": {
          "item": {
            "properties": {
              "abandonedReportExpected": {
                "type": "boolean"
              },
              "activeSecondsElapsed": {
                "format": "int32",
                "pattern": "^-?(?:0|[1-9]\\d*)$",
                "type": [
                  "integer",
                  "string"
                ]
              },
              "allowStepDown": {
                "type": "boolean"
              },
              "assignmentAssigneeId": {
                "format": "uuid",
                "type": [
                  "null",
                  "string"
                ]
              },
              "assignmentAssigneeType": {
                "enum": [
                  "Student",
                  "Roster",
                  "TeamSet",
                  null
                ]
              },
              "assignmentId": {
                "format": "uuid",
                "type": [
                  "null",
                  "string"
                ]
              },
              "assignmentTitle": {
                "type": [
                  "null",
                  "string"
                ]
              },
              "challengeType": {
                "enum": [
                  "SocraticConstraint",
                  "Adversary",
                  "DevilsAdvocateLoop",
                  "CounterfactualReasoning",
                  "AnalogyConstruction",
                  "ModelConstruction",
                  null
                ]
              },
              "checkpoints": {
                "items": {
                  "properties": {
                    "attemptedAtTurn": {
                      "format": "int32",
                      "pattern": "^-?(?:0|[1-9]\\d*)$",
                      "type": [
                        "null",
                        "integer",
                        "string"
                      ]
                    },
                    "checkpointId": {
                      "type": "string"
                    },
                    "description": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "failedAtTurn": {
                      "format": "int32",
                      "pattern": "^-?(?:0|[1-9]\\d*)$",
                      "type": [
                        "null",
                        "integer",
                        "string"
                      ]
                    },
                    "hintLevelAtMet": {
                      "format": "int32",
                      "pattern": "^-?(?:0|[1-9]\\d*)$",
                      "type": [
                        "null",
                        "integer",
                        "string"
                      ]
                    },
                    "id": {
                      "format": "uuid",
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "kind": {
                      "enum": [
                        "Positive",
                        "Negative"
                      ]
                    },
                    "met": {
                      "type": "boolean"
                    },
                    "metAtTurn": {
                      "format": "int32",
                      "pattern": "^-?(?:0|[1-9]\\d*)$",
                      "type": [
                        "null",
                        "integer",
                        "string"
                      ]
                    },
                    "metInMode": {
                      "enum": [
                        "Guided",
                        "Standard",
                        "Challenge",
                        null
                      ]
                    },
                    "metadataJson": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "required": {
                      "type": "boolean"
                    },
                    "sequence": {
                      "format": "int32",
                      "pattern": "^-?(?:0|[1-9]\\d*)$",
                      "type": [
                        "integer",
                        "string"
                      ]
                    },
                    "sessionId": {
                      "format": "uuid",
                      "type": "string"
                    },
                    "stepCredit": {
                      "format": "double",
                      "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d\u002B)?$",
                      "type": [
                        "null",
                        "number",
                        "string"
                      ]
                    },
                    "tenantId": {
                      "format": "uuid",
                      "type": "string"
                    }
                  },
                  "type": "object"
                },
                "type": [
                  "null",
                  "array"
                ]
              },
              "completedAt": {
                "format": "date-time",
                "type": [
                  "null",
                  "string"
                ]
              },
              "evaluationGaveUpAtUtc": {
                "format": "date-time",
                "type": [
                  "null",
                  "string"
                ]
              },
              "evaluations": {
                "items": {
                  "properties": {
                    "completionType": {
                      "enum": [
                        "Full",
                        "Partial",
                        "TimedOut"
                      ]
                    },
                    "dimensionScores": {
                      "items": {
                        "properties": {
                          "dimensionName": {
                            "type": "string"
                          },
                          "evaluationId": {
                            "format": "uuid",
                            "type": "string"
                          },
                          "id": {
                            "format": "uuid",
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "rationale": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "score": {
                            "format": "int32",
                            "pattern": "^-?(?:0|[1-9]\\d*)$",
                            "type": [
                              "integer",
                              "string"
                            ]
                          },
                          "tenantId": {
                            "format": "uuid",
                            "type": "string"
                          }
                        },
                        "type": "object"
                      },
                      "type": [
                        "null",
                        "array"
                      ]
                    },
                    "hintLevelReached": {
                      "format": "int32",
                      "pattern": "^-?(?:0|[1-9]\\d*)$",
                      "type": [
                        "integer",
                        "string"
                      ]
                    },
                    "id": {
                      "format": "uuid",
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "masteryBand": {
                      "enum": [
                        "Beginning",
                        "Developing",
                        "Proficient",
                        "Mastered",
                        null
                      ]
                    },
                    "narrativeSummary": {
                      "type": "string"
                    },
                    "overallScore": {
                      "format": "double",
                      "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d\u002B)?$",
                      "type": [
                        "number",
                        "string"
                      ]
                    },
                    "recommendedNextType": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "sessionId": {
                      "format": "uuid",
                      "type": "string"
                    },
                    "stepCreditPercent": {
                      "format": "double",
                      "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d\u002B)?$",
                      "type": [
                        "null",
                        "number",
                        "string"
                      ]
                    },
                    "tenantId": {
                      "format": "uuid",
                      "type": "string"
                    }
                  },
                  "type": "object"
                },
                "type": [
                  "null",
                  "array"
                ]
              },
              "generatedContractJson": {
                "type": [
                  "null",
                  "string"
                ]
              },
              "hasStudentTurn": {
                "type": "boolean"
              },
              "hintLevel": {
                "format": "int32",
                "pattern": "^-?(?:0|[1-9]\\d*)$",
                "type": [
                  "integer",
                  "string"
                ]
              },
              "id": {
                "format": "uuid",
                "type": [
                  "null",
                  "string"
                ]
              },
              "locale": {
                "type": "string"
              },
              "masteryBand": {
                "enum": [
                  "Beginning",
                  "Developing",
                  "Proficient",
                  "Mastered",
                  null
                ]
              },
              "maxStudentTurns": {
                "format": "int32",
                "pattern": "^-?(?:0|[1-9]\\d*)$",
                "type": [
                  "null",
                  "integer",
                  "string"
                ]
              },
              "pauseReason": {
                "type": [
                  "null",
                  "string"
                ]
              },
              "safeguardFlags": {
                "items": {
                  "properties": {
                    "dispositionReason": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "id": {
                      "format": "uuid",
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "reason": {
                      "type": "string"
                    },
                    "reportedById": {
                      "format": "uuid",
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "resolvedAt": {
                      "format": "date-time",
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "resolvedById": {
                      "format": "uuid",
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "reviewerNotes": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "sessionId": {
                      "format": "uuid",
                      "type": "string"
                    },
                    "source": {
                      "enum": [
                        "Agent",
                        "MemberReport"
                      ]
                    },
                    "status": {
                      "enum": [
                        "Open",
                        "Cleared",
                        "Escalated"
                      ]
                    },
                    "studentId": {
                      "format": "uuid",
                      "type": "string"
                    },
                    "teamChatMessageId": {
                      "format": "uuid",
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "tenantId": {
                      "format": "uuid",
                      "type": "string"
                    }
                  },
                  "type": "object"
                },
                "type": [
                  "null",
                  "array"
                ]
              },
              "scenario": {
                "type": [
                  "null",
                  "string"
                ]
              },
              "startedAt": {
                "format": "date-time",
                "type": [
                  "null",
                  "string"
                ]
              },
              "status": {
                "enum": [
                  "Created",
                  "InProgress",
                  "Paused",
                  "PausedError",
                  "PausedSafeguard",
                  "Completing",
                  "Completed",
                  "CompletedPartial",
                  "CompletedPendingEval",
                  "Abandoned",
                  "TimedOut",
                  "Cancelled",
                  "PausedIntegrity"
                ]
              },
              "studentDisplayName": {
                "type": [
                  "null",
                  "string"
                ]
              },
              "studentId": {
                "format": "uuid",
                "type": "string"
              },
              "supportMode": {
                "enum": [
                  "Guided",
                  "Standard",
                  "Challenge"
                ]
              },
              "teamId": {
                "format": "uuid",
                "type": [
                  "null",
                  "string"
                ]
              },
              "teamName": {
                "type": [
                  "null",
                  "string"
                ]
              },
              "templateId": {
                "format": "uuid",
                "type": [
                  "null",
                  "string"
                ]
              },
              "templateTitle": {
                "type": [
                  "null",
                  "string"
                ]
              },
              "templateVersionId": {
                "format": "uuid",
                "type": "string"
              },
              "templateVersionNumber": {
                "format": "int32",
                "pattern": "^-?(?:0|[1-9]\\d*)$",
                "type": [
                  "null",
                  "integer",
                  "string"
                ]
              },
              "tenantId": {
                "format": "uuid",
                "type": "string"
              },
              "theme": {
                "type": [
                  "null",
                  "string"
                ]
              },
              "timeLimitSeconds": {
                "format": "int32",
                "pattern": "^-?(?:0|[1-9]\\d*)$",
                "type": [
                  "null",
                  "integer",
                  "string"
                ]
              },
              "turnCount": {
                "format": "int32",
                "pattern": "^-?(?:0|[1-9]\\d*)$",
                "type": [
                  "integer",
                  "string"
                ]
              },
              "turns": {
                "items": {
                  "properties": {
                    "authorDisplayName": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "authorId": {
                      "format": "uuid",
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "clientTurnId": {
                      "format": "uuid",
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "content": {
                      "type": "string"
                    },
                    "contentLocale": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "id": {
                      "format": "uuid",
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "inputTokens": {
                      "format": "int32",
                      "pattern": "^-?(?:0|[1-9]\\d*)$",
                      "type": [
                        "null",
                        "integer",
                        "string"
                      ]
                    },
                    "outputTokens": {
                      "format": "int32",
                      "pattern": "^-?(?:0|[1-9]\\d*)$",
                      "type": [
                        "null",
                        "integer",
                        "string"
                      ]
                    },
                    "role": {
                      "enum": [
                        "Student",
                        "Agent",
                        "System"
                      ]
                    },
                    "sequence": {
                      "format": "int32",
                      "pattern": "^-?(?:0|[1-9]\\d*)$",
                      "type": [
                        "integer",
                        "string"
                      ]
                    },
                    "sessionId": {
                      "format": "uuid",
                      "type": "string"
                    },
                    "tenantId": {
                      "format": "uuid",
                      "type": "string"
                    },
                    "visibleToStudent": {
                      "type": "boolean"
                    }
                  },
                  "type": "object"
                },
                "type": [
                  "null",
                  "array"
                ]
              },
              "turnsWithoutNewCheckpoint": {
                "format": "int32",
                "pattern": "^-?(?:0|[1-9]\\d*)$",
                "type": [
                  "integer",
                  "string"
                ]
              }
            },
            "type": "object"
          },
          "tenantInfo": {
            "properties": {
              "name": {
                "type": [
                  "null",
                  "string"
                ]
              },
              "tenantId": {
                "format": "uuid",
                "type": "string"
              }
            },
            "type": "object"
          }
        },
        "type": "object"
      },
      "PartnerTurnInput": {
        "properties": {
          "clientTurnId": {
            "format": "uuid",
            "type": "string"
          },
          "studentMessage": {
            "type": "string"
          }
        },
        "required": [
          "clientTurnId",
          "studentMessage"
        ],
        "type": "object"
      },
      "StartSessionRequest": {
        "properties": {
          "assignmentId": {
            "description": "Refused when non-null: partner sessions use library challenges. Omit this field.",
            "format": "uuid",
            "type": [
              "null",
              "string"
            ]
          },
          "locale": {
            "type": [
              "null",
              "string"
            ]
          },
          "studentId": {
            "description": "Ignored: the server selects the learner from the subject in the URL.",
            "format": "uuid",
            "type": "string"
          },
          "supportMode": {
            "$ref": "#/components/schemas/SupportMode"
          },
          "templateVersionId": {
            "format": "uuid",
            "type": "string"
          },
          "tenantId": {
            "description": "Ignored: the server selects the partner\u0027s tenant.",
            "format": "uuid",
            "type": "string"
          }
        },
        "required": [
          "templateVersionId"
        ],
        "type": "object"
      },
      "SupportMode": {
        "enum": [
          "Guided",
          "Standard",
          "Challenge"
        ]
      }
    },
    "securitySchemes": {
      "PartnerBearer": {
        "bearerFormat": "JWT",
        "description": "Use the access_token returned by private_key_jwt client_credentials authentication. Default lifetime: 15 minutes. Entra and LTI launch tokens are refused.",
        "scheme": "bearer",
        "type": "http"
      },
      "PartnerClientCredentials": {
        "description": "Client authentication is private_key_jwt, not a client secret. Send an RS256 JWT with kid, iss=sub=clientId, aud=the exact public token URL, exp within five minutes and a single-use jti. Publish the public key at the registered JWKS URL. Request scope optionally narrows the configured strings. Routes enforce partner authentication and learner ownership; there is no per-operation scope enforcement.",
        "flows": {
          "clientCredentials": {
            "scopes": {},
            "tokenUrl": "https://api.example.invalid/partner/oauth/token"
          }
        },
        "type": "oauth2"
      }
    }
  },
  "info": {
    "description": "Server-to-server integration. Available only when Features:PartnerApi is enabled. The live document requires a partner bearer token; a public snapshot ships with the integration guide. The public snapshot uses the apiHost server variable and an absolute placeholder tokenUrl. Replace api.example.invalid in both with the public API host supplied during onboarding; the live document uses PartnerApi:TokenEndpoint.",
    "title": "AI Challenge Partner API",
    "version": "v1"
  },
  "openapi": "3.1.1",
  "paths": {
    "/partner/oauth/token": {
      "post": {
        "description": "Authenticate with private_key_jwt. Repeated form fields are refused. Limited per caller address (default 60/minute). Responses are no-store.",
        "requestBody": {
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "properties": {
                  "client_assertion": {
                    "description": "RS256 private_key_jwt client assertion; never send a shared client secret.",
                    "maxLength": 16384,
                    "type": "string"
                  },
                  "client_assertion_type": {
                    "const": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
                    "type": "string"
                  },
                  "grant_type": {
                    "const": "client_credentials",
                    "type": "string"
                  },
                  "scope": {
                    "description": "Optional space-delimited scopes. Omit for all configured scopes; the intersection must be nonempty.",
                    "type": "string"
                  }
                },
                "required": [
                  "grant_type",
                  "client_assertion_type",
                  "client_assertion"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "access_token": {
                      "type": "string"
                    },
                    "expires_in": {
                      "type": "integer"
                    },
                    "scope": {
                      "type": "string"
                    },
                    "token_type": {
                      "const": "Bearer",
                      "type": "string"
                    }
                  },
                  "required": [
                    "access_token",
                    "token_type",
                    "expires_in",
                    "scope"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Bearer token"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "OAuth error: invalid_request, unsupported_grant_type, invalid_client or invalid_scope."
          },
          "429": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Rate limit reached. Back off using Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "minimum": 1,
                  "type": "integer"
                }
              }
            }
          },
          "503": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Temporarily unavailable, including fail-closed rate limiting when Redis is unavailable. Back off using Retry-After when present.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "minimum": 1,
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [],
        "tags": [
          "Authentication"
        ]
      }
    },
    "/partner/v1/challenges": {
      "get": {
        "description": "Lists the learner\u0027s age-gated library challenges. Returns only the first page of at most 20; paging and filter parameters are not accepted by this endpoint.",
        "parameters": [
          {
            "in": "query",
            "name": "subject",
            "required": true,
            "schema": {
              "description": "Existing partner learner subject.",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "data": {
                      "items": {
                        "properties": {
                          "attemptsRemaining": {
                            "format": "int32",
                            "pattern": "^-?(?:0|[1-9]\\d*)$",
                            "type": [
                              "null",
                              "integer",
                              "string"
                            ]
                          },
                          "challengeType": {
                            "enum": [
                              "SocraticConstraint",
                              "Adversary",
                              "DevilsAdvocateLoop",
                              "CounterfactualReasoning",
                              "AnalogyConstruction",
                              "ModelConstruction"
                            ]
                          },
                          "description": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "difficulty": {
                            "format": "int32",
                            "pattern": "^-?(?:0|[1-9]\\d*)$",
                            "type": [
                              "null",
                              "integer",
                              "string"
                            ]
                          },
                          "labels": {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          "locale": {
                            "type": "string"
                          },
                          "minimumAge": {
                            "format": "int32",
                            "pattern": "^-?(?:0|[1-9]\\d*)$",
                            "type": [
                              "null",
                              "integer",
                              "string"
                            ]
                          },
                          "newRunBlockedReason": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "source": {
                            "enum": [
                              "BuiltIn",
                              "Own",
                              "Community"
                            ]
                          },
                          "standards": {
                            "items": {
                              "properties": {
                                "code": {
                                  "type": "string"
                                },
                                "frameworkCode": {
                                  "type": "string"
                                },
                                "frameworkName": {
                                  "type": [
                                    "null",
                                    "string"
                                  ]
                                },
                                "frameworkNotice": {
                                  "type": [
                                    "null",
                                    "string"
                                  ]
                                },
                                "gradeHigh": {
                                  "format": "int32",
                                  "pattern": "^-?(?:0|[1-9]\\d*)$",
                                  "type": [
                                    "null",
                                    "integer",
                                    "string"
                                  ]
                                },
                                "gradeLow": {
                                  "format": "int32",
                                  "pattern": "^-?(?:0|[1-9]\\d*)$",
                                  "type": [
                                    "null",
                                    "integer",
                                    "string"
                                  ]
                                },
                                "isRetired": {
                                  "type": "boolean"
                                },
                                "shortLabel": {
                                  "type": [
                                    "null",
                                    "string"
                                  ]
                                },
                                "sourceUrl": {
                                  "type": [
                                    "null",
                                    "string"
                                  ]
                                }
                              },
                              "type": "object"
                            },
                            "type": "array"
                          },
                          "subject": {
                            "enum": [
                              "EverydayReasoning",
                              "PhilosophyEthics",
                              "DebateCivics",
                              "AiTechnology",
                              "Science",
                              "History",
                              "Mathematics",
                              "Economics",
                              "LiteratureLanguage",
                              null
                            ]
                          },
                          "templateId": {
                            "format": "uuid",
                            "type": "string"
                          },
                          "templateVersionId": {
                            "format": "uuid",
                            "type": "string"
                          },
                          "title": {
                            "type": "string"
                          },
                          "versionNumber": {
                            "format": "int32",
                            "pattern": "^-?(?:0|[1-9]\\d*)$",
                            "type": [
                              "integer",
                              "string"
                            ]
                          }
                        },
                        "type": "object"
                      },
                      "type": "array"
                    },
                    "pageIndex": {
                      "format": "int32",
                      "pattern": "^-?(?:0|[1-9]\\d*)$",
                      "type": [
                        "integer",
                        "string"
                      ]
                    },
                    "pageSize": {
                      "format": "int32",
                      "pattern": "^-?(?:0|[1-9]\\d*)$",
                      "type": [
                        "integer",
                        "string"
                      ]
                    },
                    "total": {
                      "format": "int32",
                      "pattern": "^-?(?:0|[1-9]\\d*)$",
                      "type": [
                        "integer",
                        "string"
                      ]
                    }
                  },
                  "type": "object"
                }
              }
            },
            "description": "Success"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "type": "object"
                }
              },
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Invalid request or domain validation failure. Some boundary checks return application/json {error}."
          },
          "401": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Missing or invalid bearer token."
          },
          "403": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Wrong token audience or a domain access refusal."
          },
          "404": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Feature disabled, or client, learner or session unavailable to this caller."
          },
          "429": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Rate limit reached. Back off using Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "minimum": 1,
                  "type": "integer"
                }
              }
            }
          },
          "503": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Temporarily unavailable, including fail-closed rate limiting when Redis is unavailable. Back off using Retry-After when present.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "minimum": 1,
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "PartnerBearer": []
          }
        ],
        "tags": [
          "Challenges"
        ]
      }
    },
    "/partner/v1/learners/{subject}": {
      "put": {
        "parameters": [
          {
            "in": "path",
            "name": "subject",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PartnerLearnerRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "ageBand": {
                      "enum": [
                        "Age13To15",
                        "Age16To17",
                        "Adult"
                      ],
                      "type": "string"
                    },
                    "displayName": {
                      "type": "string"
                    },
                    "locale": {
                      "type": "string"
                    },
                    "subject": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "subject",
                    "ageBand",
                    "displayName",
                    "locale"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Existing learner updated"
          },
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "ageBand": {
                      "enum": [
                        "Age13To15",
                        "Age16To17",
                        "Adult"
                      ],
                      "type": "string"
                    },
                    "displayName": {
                      "type": "string"
                    },
                    "locale": {
                      "type": "string"
                    },
                    "subject": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "subject",
                    "ageBand",
                    "displayName",
                    "locale"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Learner created",
            "headers": {
              "Location": {
                "description": "Relative URL of the learner or session, or the turn status to poll.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "type": "object"
                }
              },
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Invalid request or domain validation failure. Some boundary checks return application/json {error}."
          },
          "401": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Missing or invalid bearer token."
          },
          "403": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Wrong token audience or a domain access refusal."
          },
          "404": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Feature disabled, or client, learner or session unavailable to this caller."
          },
          "429": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Rate limit reached. Back off using Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "minimum": 1,
                  "type": "integer"
                }
              }
            }
          },
          "503": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Temporarily unavailable, including fail-closed rate limiting when Redis is unavailable. Back off using Retry-After when present.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "minimum": 1,
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "PartnerBearer": []
          }
        ],
        "tags": [
          "Learners"
        ]
      }
    },
    "/partner/v1/learners/{subject}/sessions": {
      "post": {
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StartSessionRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerSessionResponse"
                }
              }
            },
            "description": "Session created",
            "headers": {
              "Location": {
                "description": "Relative URL of the learner or session, or the turn status to poll.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "type": "object"
                }
              },
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Invalid request or domain validation failure. Some boundary checks return application/json {error}."
          },
          "401": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Missing or invalid bearer token."
          },
          "403": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Wrong token audience or a domain access refusal."
          },
          "404": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Feature disabled, or client, learner or session unavailable to this caller."
          },
          "409": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Session state or concurrent change conflict. A pending turn conflict includes clientTurnId."
          },
          "422": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "AI content-filter refusal. A blocked opening does not start a session; a blocked turn fails the turn (Failed in turn status) and pauses the session until the learner resumes."
          },
          "429": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Rate limit or daily entitlement limit reached. Back off using Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "minimum": 1,
                  "type": "integer"
                }
              }
            }
          },
          "503": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Temporarily unavailable: AI sessions paused by an administrator or daily spend limit, AI provider busy, or fail-closed rate limiting when Redis is unavailable. Back off using Retry-After when present.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "minimum": 1,
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "PartnerBearer": []
          }
        ],
        "tags": [
          "Sessions"
        ]
      }
    },
    "/partner/v1/learners/{subject}/sessions/{id}": {
      "get": {
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerSessionResponse"
                }
              }
            },
            "description": "Success"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "type": "object"
                }
              },
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Invalid request or domain validation failure. Some boundary checks return application/json {error}."
          },
          "401": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Missing or invalid bearer token."
          },
          "403": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Wrong token audience or a domain access refusal."
          },
          "404": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Feature disabled, or client, learner or session unavailable to this caller."
          },
          "429": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Rate limit reached. Back off using Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "minimum": 1,
                  "type": "integer"
                }
              }
            }
          },
          "503": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Temporarily unavailable, including fail-closed rate limiting when Redis is unavailable. Back off using Retry-After when present.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "minimum": 1,
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "PartnerBearer": []
          }
        ],
        "tags": [
          "Sessions"
        ]
      }
    },
    "/partner/v1/learners/{subject}/sessions/{id}/abandon": {
      "post": {
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerSessionResponse"
                }
              }
            },
            "description": "Success"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "type": "object"
                }
              },
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Invalid request or domain validation failure. Some boundary checks return application/json {error}."
          },
          "401": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Missing or invalid bearer token."
          },
          "403": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Wrong token audience or a domain access refusal."
          },
          "404": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Feature disabled, or client, learner or session unavailable to this caller."
          },
          "409": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Session state or concurrent change conflict. A pending turn conflict includes clientTurnId."
          },
          "429": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Rate limit reached. Back off using Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "minimum": 1,
                  "type": "integer"
                }
              }
            }
          },
          "503": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Temporarily unavailable, including fail-closed rate limiting when Redis is unavailable. Back off using Retry-After when present.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "minimum": 1,
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "PartnerBearer": []
          }
        ],
        "tags": [
          "Sessions"
        ]
      }
    },
    "/partner/v1/learners/{subject}/sessions/{id}/hint": {
      "post": {
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerSessionResponse"
                }
              }
            },
            "description": "Success"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "type": "object"
                }
              },
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Invalid request or domain validation failure. Some boundary checks return application/json {error}."
          },
          "401": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Missing or invalid bearer token."
          },
          "403": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Wrong token audience or a domain access refusal."
          },
          "404": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Feature disabled, or client, learner or session unavailable to this caller."
          },
          "409": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Session state or concurrent change conflict. A pending turn conflict includes clientTurnId."
          },
          "429": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Rate limit reached. Back off using Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "minimum": 1,
                  "type": "integer"
                }
              }
            }
          },
          "503": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Temporarily unavailable, including fail-closed rate limiting when Redis is unavailable. Back off using Retry-After when present.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "minimum": 1,
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "PartnerBearer": []
          }
        ],
        "tags": [
          "Sessions"
        ]
      }
    },
    "/partner/v1/learners/{subject}/sessions/{id}/pause": {
      "post": {
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerSessionResponse"
                }
              }
            },
            "description": "Success"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "type": "object"
                }
              },
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Invalid request or domain validation failure. Some boundary checks return application/json {error}."
          },
          "401": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Missing or invalid bearer token."
          },
          "403": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Wrong token audience or a domain access refusal."
          },
          "404": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Feature disabled, or client, learner or session unavailable to this caller."
          },
          "409": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Session state or concurrent change conflict. A pending turn conflict includes clientTurnId."
          },
          "429": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Rate limit reached. Back off using Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "minimum": 1,
                  "type": "integer"
                }
              }
            }
          },
          "503": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Temporarily unavailable, including fail-closed rate limiting when Redis is unavailable. Back off using Retry-After when present.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "minimum": 1,
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "PartnerBearer": []
          }
        ],
        "tags": [
          "Sessions"
        ]
      }
    },
    "/partner/v1/learners/{subject}/sessions/{id}/report": {
      "get": {
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerSessionResponse"
                }
              }
            },
            "description": "Success"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "type": "object"
                }
              },
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Invalid request or domain validation failure. Some boundary checks return application/json {error}."
          },
          "401": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Missing or invalid bearer token."
          },
          "403": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Wrong token audience or a domain access refusal."
          },
          "404": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Feature disabled, or client, learner or session unavailable to this caller."
          },
          "429": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Rate limit reached. Back off using Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "minimum": 1,
                  "type": "integer"
                }
              }
            }
          },
          "503": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Temporarily unavailable, including fail-closed rate limiting when Redis is unavailable. Back off using Retry-After when present.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "minimum": 1,
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "PartnerBearer": []
          }
        ],
        "tags": [
          "Sessions"
        ]
      }
    },
    "/partner/v1/learners/{subject}/sessions/{id}/resume": {
      "post": {
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerSessionResponse"
                }
              }
            },
            "description": "Success"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "type": "object"
                }
              },
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Invalid request or domain validation failure. Some boundary checks return application/json {error}."
          },
          "401": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Missing or invalid bearer token."
          },
          "403": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Wrong token audience or a domain access refusal."
          },
          "404": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Feature disabled, or client, learner or session unavailable to this caller."
          },
          "409": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Session state or concurrent change conflict. A pending turn conflict includes clientTurnId."
          },
          "429": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Rate limit reached. Back off using Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "minimum": 1,
                  "type": "integer"
                }
              }
            }
          },
          "503": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Temporarily unavailable, including fail-closed rate limiting when Redis is unavailable. Back off using Retry-After when present.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "minimum": 1,
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "PartnerBearer": []
          }
        ],
        "tags": [
          "Sessions"
        ]
      }
    },
    "/partner/v1/learners/{subject}/sessions/{id}/turns": {
      "post": {
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PartnerTurnInput"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "clientTurnId": {
                      "format": "uuid",
                      "type": "string"
                    },
                    "error": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "id": {
                      "format": "uuid",
                      "type": "string"
                    },
                    "reply": {
                      "properties": {
                        "authorDisplayName": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "authorId": {
                          "format": "uuid",
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "clientTurnId": {
                          "format": "uuid",
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "content": {
                          "type": "string"
                        },
                        "contentLocale": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "id": {
                          "format": "uuid",
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "inputTokens": {
                          "format": "int32",
                          "pattern": "^-?(?:0|[1-9]\\d*)$",
                          "type": [
                            "null",
                            "integer",
                            "string"
                          ]
                        },
                        "outputTokens": {
                          "format": "int32",
                          "pattern": "^-?(?:0|[1-9]\\d*)$",
                          "type": [
                            "null",
                            "integer",
                            "string"
                          ]
                        },
                        "role": {
                          "enum": [
                            "Student",
                            "Agent",
                            "System"
                          ]
                        },
                        "sequence": {
                          "format": "int32",
                          "pattern": "^-?(?:0|[1-9]\\d*)$",
                          "type": [
                            "integer",
                            "string"
                          ]
                        },
                        "sessionId": {
                          "format": "uuid",
                          "type": "string"
                        },
                        "tenantId": {
                          "format": "uuid",
                          "type": "string"
                        },
                        "visibleToStudent": {
                          "type": "boolean"
                        }
                      },
                      "type": "object"
                    },
                    "status": {
                      "enum": [
                        "Pending",
                        "Done",
                        "Failed"
                      ]
                    },
                    "turnId": {
                      "format": "uuid",
                      "type": [
                        "null",
                        "string"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "clientTurnId",
                    "status",
                    "turnId",
                    "error"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Turn accepted; poll Location. Duplicate clientTurnId returns the existing request.",
            "headers": {
              "Location": {
                "description": "Relative URL of the learner or session, or the turn status to poll.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "type": "object"
                }
              },
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Invalid request or domain validation failure. Some boundary checks return application/json {error}."
          },
          "401": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Missing or invalid bearer token."
          },
          "403": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Wrong token audience or a domain access refusal."
          },
          "404": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Feature disabled, or client, learner or session unavailable to this caller."
          },
          "409": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Session state or concurrent change conflict. A pending turn conflict includes clientTurnId."
          },
          "429": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Rate limit reached. Back off using Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "minimum": 1,
                  "type": "integer"
                }
              }
            }
          },
          "503": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Temporarily unavailable: AI sessions paused by an administrator or daily spend limit, or fail-closed rate limiting when Redis is unavailable. Back off using Retry-After when present.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "minimum": 1,
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "PartnerBearer": []
          }
        ],
        "tags": [
          "Turns"
        ]
      }
    },
    "/partner/v1/learners/{subject}/sessions/{id}/turns/{clientTurnId}": {
      "get": {
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "in": "path",
            "name": "clientTurnId",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "clientTurnId": {
                      "format": "uuid",
                      "type": "string"
                    },
                    "error": {
                      "type": [
                        "null",
                        "string"
                      ]
                    },
                    "id": {
                      "format": "uuid",
                      "type": "string"
                    },
                    "reply": {
                      "properties": {
                        "authorDisplayName": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "authorId": {
                          "format": "uuid",
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "clientTurnId": {
                          "format": "uuid",
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "content": {
                          "type": "string"
                        },
                        "contentLocale": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "id": {
                          "format": "uuid",
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "inputTokens": {
                          "format": "int32",
                          "pattern": "^-?(?:0|[1-9]\\d*)$",
                          "type": [
                            "null",
                            "integer",
                            "string"
                          ]
                        },
                        "outputTokens": {
                          "format": "int32",
                          "pattern": "^-?(?:0|[1-9]\\d*)$",
                          "type": [
                            "null",
                            "integer",
                            "string"
                          ]
                        },
                        "role": {
                          "enum": [
                            "Student",
                            "Agent",
                            "System"
                          ]
                        },
                        "sequence": {
                          "format": "int32",
                          "pattern": "^-?(?:0|[1-9]\\d*)$",
                          "type": [
                            "integer",
                            "string"
                          ]
                        },
                        "sessionId": {
                          "format": "uuid",
                          "type": "string"
                        },
                        "tenantId": {
                          "format": "uuid",
                          "type": "string"
                        },
                        "visibleToStudent": {
                          "type": "boolean"
                        }
                      },
                      "type": "object"
                    },
                    "status": {
                      "enum": [
                        "Pending",
                        "Done",
                        "Failed"
                      ]
                    },
                    "turnId": {
                      "format": "uuid",
                      "type": [
                        "null",
                        "string"
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "clientTurnId",
                    "status",
                    "turnId",
                    "error"
                  ],
                  "type": "object"
                }
              }
            },
            "description": "Success"
          },
          "400": {
            "content": {
              "application/json": {
                "schema": {
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ],
                  "type": "object"
                }
              },
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Invalid request or domain validation failure. Some boundary checks return application/json {error}."
          },
          "401": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Missing or invalid bearer token."
          },
          "403": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Wrong token audience or a domain access refusal."
          },
          "404": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Feature disabled, or client, learner or session unavailable to this caller."
          },
          "429": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Rate limit reached. Back off using Retry-After.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "minimum": 1,
                  "type": "integer"
                }
              }
            }
          },
          "503": {
            "content": {
              "application/problem\u002Bjson": {
                "schema": {
                  "$ref": "#/components/schemas/PartnerProblem"
                }
              }
            },
            "description": "Temporarily unavailable, including fail-closed rate limiting when Redis is unavailable. Back off using Retry-After when present.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "minimum": 1,
                  "type": "integer"
                }
              }
            }
          }
        },
        "security": [
          {
            "PartnerBearer": []
          }
        ],
        "tags": [
          "Turns"
        ]
      }
    }
  },
  "servers": [
    {
      "url": "https://{apiHost}",
      "variables": {
        "apiHost": {
          "default": "api.example.invalid",
          "description": "Replace with the public API host supplied during onboarding."
        }
      }
    }
  ],
  "tags": [
    {
      "name": "Authentication"
    },
    {
      "name": "Learners"
    },
    {
      "name": "Challenges"
    },
    {
      "name": "Sessions"
    },
    {
      "name": "Turns"
    }
  ],
  "webhooks": {
    "evaluation.ready": {
      "post": {
        "description": "POST to the configured WebhookUrl. At-least-once: deduplicate by X-Event-Id. Verify a constant-time HMAC-SHA256 comparison over UTF-8 X-Timestamp \u002B \u0027.\u0027 \u002B exact raw body bytes, using the issued secret\u0027s UTF-8 bytes (do not base64-decode). Signature is lowercase hex. Reject timestamps more than 300 seconds from your clock. Timestamp/signature change on retry; event id stays fixed. Default: eight attempts, doubling from 30 seconds, capped at one day; minute scheduling can delay delivery. Return any 2xx promptly. Other statuses/timeouts retry; inactive or unconfigured clients and ineligible learners abandon unsent. Secret rotation applies on the next attempt, including queued deliveries.",
        "parameters": [
          {
            "in": "header",
            "name": "X-Event-Id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "X-Timestamp",
            "required": true,
            "schema": {
              "description": "Unix seconds at this attempt.",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "X-Signature",
            "required": true,
            "schema": {
              "description": "Lowercase hex HMAC-SHA256(secret UTF-8, timestamp \u002B \u0027.\u0027 \u002B raw body).",
              "pattern": "^[0-9a-f]{64}$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "createdAt": {
                    "format": "date-time",
                    "type": "string"
                  },
                  "data": {
                    "properties": {
                      "completionType": {
                        "enum": [
                          "Full",
                          "Partial",
                          "TimedOut"
                        ],
                        "type": "string"
                      },
                      "masteryBand": {
                        "enum": [
                          "Beginning",
                          "Developing",
                          "Proficient",
                          "Mastered",
                          null
                        ],
                        "type": [
                          "null",
                          "string"
                        ]
                      },
                      "overallScore": {
                        "maximum": 100,
                        "minimum": 0,
                        "type": "number"
                      },
                      "sessionId": {
                        "format": "uuid",
                        "type": "string"
                      },
                      "stepCreditPercent": {
                        "maximum": 100,
                        "minimum": 0,
                        "type": [
                          "null",
                          "number"
                        ]
                      },
                      "subject": {
                        "description": "Partner-assigned opaque learner subject.",
                        "type": "string"
                      }
                    },
                    "required": [
                      "overallScore",
                      "completionType",
                      "masteryBand",
                      "stepCreditPercent",
                      "subject",
                      "sessionId"
                    ],
                    "type": "object"
                  },
                  "id": {
                    "format": "uuid",
                    "type": "string"
                  },
                  "type": {
                    "const": "evaluation.ready",
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "type",
                  "createdAt",
                  "data"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Accepted; any 2xx marks Sent."
          }
        },
        "security": [],
        "summary": "evaluation.ready"
      }
    },
    "safeguard.flagged": {
      "post": {
        "description": "POST to the configured WebhookUrl. At-least-once: deduplicate by X-Event-Id. Verify a constant-time HMAC-SHA256 comparison over UTF-8 X-Timestamp \u002B \u0027.\u0027 \u002B exact raw body bytes, using the issued secret\u0027s UTF-8 bytes (do not base64-decode). Signature is lowercase hex. Reject timestamps more than 300 seconds from your clock. Timestamp/signature change on retry; event id stays fixed. Default: eight attempts, doubling from 30 seconds, capped at one day; minute scheduling can delay delivery. Return any 2xx promptly. Other statuses/timeouts retry; inactive or unconfigured clients and ineligible learners abandon unsent. Secret rotation applies on the next attempt, including queued deliveries.",
        "parameters": [
          {
            "in": "header",
            "name": "X-Event-Id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "X-Timestamp",
            "required": true,
            "schema": {
              "description": "Unix seconds at this attempt.",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "X-Signature",
            "required": true,
            "schema": {
              "description": "Lowercase hex HMAC-SHA256(secret UTF-8, timestamp \u002B \u0027.\u0027 \u002B raw body).",
              "pattern": "^[0-9a-f]{64}$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "createdAt": {
                    "format": "date-time",
                    "type": "string"
                  },
                  "data": {
                    "properties": {
                      "category": {
                        "const": "safeguarding",
                        "type": "string"
                      },
                      "sessionId": {
                        "format": "uuid",
                        "type": "string"
                      },
                      "severity": {
                        "const": "flagged",
                        "type": "string"
                      },
                      "subject": {
                        "description": "Partner-assigned opaque learner subject.",
                        "type": "string"
                      },
                      "url": {
                        "description": "Relative learner-scoped session URL. No free-text reason or transcript is sent.",
                        "type": "string"
                      }
                    },
                    "required": [
                      "severity",
                      "category",
                      "url",
                      "subject",
                      "sessionId"
                    ],
                    "type": "object"
                  },
                  "id": {
                    "format": "uuid",
                    "type": "string"
                  },
                  "type": {
                    "const": "safeguard.flagged",
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "type",
                  "createdAt",
                  "data"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Accepted; any 2xx marks Sent."
          }
        },
        "security": [],
        "summary": "safeguard.flagged"
      }
    },
    "session.completed": {
      "post": {
        "description": "POST to the configured WebhookUrl. At-least-once: deduplicate by X-Event-Id. Verify a constant-time HMAC-SHA256 comparison over UTF-8 X-Timestamp \u002B \u0027.\u0027 \u002B exact raw body bytes, using the issued secret\u0027s UTF-8 bytes (do not base64-decode). Signature is lowercase hex. Reject timestamps more than 300 seconds from your clock. Timestamp/signature change on retry; event id stays fixed. Default: eight attempts, doubling from 30 seconds, capped at one day; minute scheduling can delay delivery. Return any 2xx promptly. Other statuses/timeouts retry; inactive or unconfigured clients and ineligible learners abandon unsent. Secret rotation applies on the next attempt, including queued deliveries.",
        "parameters": [
          {
            "in": "header",
            "name": "X-Event-Id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "X-Timestamp",
            "required": true,
            "schema": {
              "description": "Unix seconds at this attempt.",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "X-Signature",
            "required": true,
            "schema": {
              "description": "Lowercase hex HMAC-SHA256(secret UTF-8, timestamp \u002B \u0027.\u0027 \u002B raw body).",
              "pattern": "^[0-9a-f]{64}$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "createdAt": {
                    "format": "date-time",
                    "type": "string"
                  },
                  "data": {
                    "properties": {
                      "sessionId": {
                        "format": "uuid",
                        "type": "string"
                      },
                      "subject": {
                        "description": "Partner-assigned opaque learner subject.",
                        "type": "string"
                      }
                    },
                    "required": [
                      "subject",
                      "sessionId"
                    ],
                    "type": "object"
                  },
                  "id": {
                    "format": "uuid",
                    "type": "string"
                  },
                  "type": {
                    "const": "session.completed",
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "type",
                  "createdAt",
                  "data"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Accepted; any 2xx marks Sent."
          }
        },
        "security": [],
        "summary": "session.completed"
      }
    },
    "turn.completed": {
      "post": {
        "description": "POST to the configured WebhookUrl. At-least-once: deduplicate by X-Event-Id. Verify a constant-time HMAC-SHA256 comparison over UTF-8 X-Timestamp \u002B \u0027.\u0027 \u002B exact raw body bytes, using the issued secret\u0027s UTF-8 bytes (do not base64-decode). Signature is lowercase hex. Reject timestamps more than 300 seconds from your clock. Timestamp/signature change on retry; event id stays fixed. Default: eight attempts, doubling from 30 seconds, capped at one day; minute scheduling can delay delivery. Return any 2xx promptly. Other statuses/timeouts retry; inactive or unconfigured clients and ineligible learners abandon unsent. Secret rotation applies on the next attempt, including queued deliveries.",
        "parameters": [
          {
            "in": "header",
            "name": "X-Event-Id",
            "required": true,
            "schema": {
              "format": "uuid",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "X-Timestamp",
            "required": true,
            "schema": {
              "description": "Unix seconds at this attempt.",
              "type": "string"
            }
          },
          {
            "in": "header",
            "name": "X-Signature",
            "required": true,
            "schema": {
              "description": "Lowercase hex HMAC-SHA256(secret UTF-8, timestamp \u002B \u0027.\u0027 \u002B raw body).",
              "pattern": "^[0-9a-f]{64}$",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "properties": {
                  "createdAt": {
                    "format": "date-time",
                    "type": "string"
                  },
                  "data": {
                    "properties": {
                      "clientTurnId": {
                        "format": "uuid",
                        "type": "string"
                      },
                      "error": {
                        "description": "Null on done, fixed safe text on failed. Read turn status for an optional visible reply.",
                        "type": [
                          "null",
                          "string"
                        ]
                      },
                      "sessionId": {
                        "format": "uuid",
                        "type": "string"
                      },
                      "status": {
                        "enum": [
                          "done",
                          "failed"
                        ],
                        "type": "string"
                      },
                      "subject": {
                        "description": "Partner-assigned opaque learner subject.",
                        "type": "string"
                      }
                    },
                    "required": [
                      "clientTurnId",
                      "status",
                      "error",
                      "subject",
                      "sessionId"
                    ],
                    "type": "object"
                  },
                  "id": {
                    "format": "uuid",
                    "type": "string"
                  },
                  "type": {
                    "const": "turn.completed",
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "type",
                  "createdAt",
                  "data"
                ],
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "2XX": {
            "description": "Accepted; any 2xx marks Sent."
          }
        },
        "security": [],
        "summary": "turn.completed"
      }
    }
  }
}
