{
  "openapi": "3.1.0",
  "info": {
    "title": "Mentorly GraphQL API",
    "version": "1.0.0",
    "summary": "Programmatic access to the Mentorly mentorship platform through a single GraphQL endpoint.",
    "description": "The Mentorly GraphQL API gives programmatic access to the full mentoring lifecycle: onboarding, availability, matching, session booking, messaging, goals, reviews, and program analytics. It is the same API the Mentorly web application runs on, so anything a user can do in the product, an authorized API consumer (including an AI agent acting on that user's behalf) can do through this API.\n\nThis is a GraphQL API. Every request is a POST to the single `/graphql` path with a JSON body containing `query`, optional `operationName`, and optional `variables`. The complete, human-readable reference for every query, mutation, and type is published at https://mentorly.com/developers and a condensed agent-oriented summary at https://mentorly.com/developers.md.\n\nAuthentication uses admin-issued API keys sent as a bearer token. Keys act as the user they are bound to and carry scopes that cap what they may do. See https://mentorly.com/auth.md for the full credential walkthrough.\n\nRate limits: 120 requests per minute per key (Standard) or 600 (Enterprise). Successful responses include X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers. Exceeding the quota returns HTTP 429 with a Retry-After header.\n\nQuery constraints: maximum query depth 15, maximum query complexity 1000, maximum page size 20. List fields paginate with 1-indexed `page` and `per` arguments. Schema introspection is disabled in production; use the published reference instead.",
    "contact": {
      "name": "Mentorly Support",
      "email": "support@mentorly.co",
      "url": "https://mentorly.com"
    },
    "termsOfService": "https://mentorly.com/en/terms",
    "license": {
      "name": "Proprietary",
      "url": "https://mentorly.com/en/terms"
    }
  },
  "externalDocs": {
    "description": "Full GraphQL API reference (every operation and type documented)",
    "url": "https://mentorly.com/developers"
  },
  "servers": [
    {
      "url": "https://api.mentorly.co",
      "description": "Production"
    }
  ],
  "security": [
    {
      "apiKeyBearer": []
    }
  ],
  "tags": [
    {
      "name": "graphql",
      "description": "Single GraphQL endpoint carrying all queries and mutations"
    }
  ],
  "paths": {
    "/graphql": {
      "post": {
        "operationId": "executeGraphQL",
        "tags": ["graphql"],
        "summary": "Execute a GraphQL query or mutation",
        "description": "Executes a single GraphQL operation. The available operations cover users, mentors, matching, bookings, conversations, goals, reviews, surveys, and program analytics. Consult https://mentorly.com/developers for the full schema reference with per-operation descriptions, or https://mentorly.com/developers.md for a condensed markdown version.",
        "parameters": [
          {
            "name": "X-Group-Id",
            "in": "header",
            "required": false,
            "description": "Program (group) context for program-scoped queries. API-key requests fall back to the key's configured group when absent. Pass explicitly when the user belongs to more than one program.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GraphQLRequest"
              },
              "examples": {
                "viewer": {
                  "summary": "Fetch the authenticated user",
                  "value": {
                    "query": "query { viewer { id firstName lastName email } }"
                  }
                },
                "mentors": {
                  "summary": "List mentors (paginated)",
                  "value": {
                    "query": "query Mentors($page: Int, $per: Int) { mentors(page: $page, per: $per) { id firstName lastName } }",
                    "variables": { "page": 1, "per": 20 }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "GraphQL result. May contain `data`, `errors`, or both. Mutation payloads additionally expose `errors: [String]` and `errorDetails: JSON` fields for handled business-rule failures; content in those fields means the mutation did not succeed even though HTTP status is 200.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GraphQLResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GraphQLResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Back off until the reset time indicated by Retry-After before retrying.",
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKeyBearer": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "mk_live_<prefix>.<secret>",
        "description": "Admin-issued Mentorly API key sent as a bearer token: `Authorization: Bearer mk_live_<prefix>.<secret>`. Keys are bound to a user and carry scopes (read:users, write:users, read:bookings, write:bookings, read:matches, write:matches, read:analytics, read:conversations, admin) that cap what the key may do on top of the user's own permissions. There is no self-serve or automated registration; see https://mentorly.com/auth.md."
      }
    },
    "headers": {
      "XRateLimitLimit": {
        "description": "Request quota for this key per minute.",
        "schema": { "type": "integer" }
      },
      "XRateLimitRemaining": {
        "description": "Requests remaining in the current window.",
        "schema": { "type": "integer" }
      },
      "XRateLimitReset": {
        "description": "Unix timestamp at which the window resets.",
        "schema": { "type": "integer" }
      }
    },
    "schemas": {
      "GraphQLRequest": {
        "type": "object",
        "required": ["query"],
        "properties": {
          "query": {
            "type": "string",
            "description": "GraphQL query or mutation document."
          },
          "operationName": {
            "type": "string",
            "description": "Name of the operation to execute when the document contains more than one."
          },
          "variables": {
            "type": "object",
            "description": "Values for variables declared by the operation.",
            "additionalProperties": true
          }
        }
      },
      "GraphQLResponse": {
        "type": "object",
        "properties": {
          "data": {
            "description": "Result of the operation. Null or absent when the request failed before execution.",
            "type": ["object", "null"],
            "additionalProperties": true
          },
          "errors": {
            "type": "array",
            "description": "Request-level failures such as authorization or validation problems.",
            "items": {
              "$ref": "#/components/schemas/GraphQLError"
            }
          }
        }
      },
      "GraphQLError": {
        "type": "object",
        "required": ["message"],
        "properties": {
          "message": {
            "type": "string"
          },
          "path": {
            "type": "array",
            "items": {
              "type": ["string", "integer"]
            }
          },
          "extensions": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "description": "Machine-readable error code.",
                "enum": [
                  "VALIDATION_ERROR",
                  "unauthorized",
                  "forbidden",
                  "NOT_FOUND_ERROR"
                ]
              },
              "details": {
                "description": "Validation messages when code is VALIDATION_ERROR.",
                "type": ["object", "array", "null"]
              }
            }
          }
        }
      }
    }
  }
}
