{
	"openapi": "3.1.0",
	"info": {
		"title": "Majestic Labs Public API",
		"version": "1.0.0",
		"description": "Public machine-readable surface of majesticlabs.dev. Stable operations are versioned by URL path prefix (/api/v1); breaking changes require a new major prefix and the previous prefix keeps working. The inquiry endpoint receives contact requests; the well-known endpoint publishes RFC 9728 protected-resource metadata for the site's MCP resource. Site content itself is available as Markdown: append .md to any primary page URL or send Accept: text/markdown.",
		"contact": {
			"name": "Majestic Labs",
			"url": "https://majesticlabs.dev/llms.txt"
		}
	},
	"servers": [
		{
			"url": "https://majesticlabs.dev"
		}
	],
	"paths": {
		"/api/v1/inquiry": {
			"post": {
				"operationId": "submitInquiry",
				"summary": "Submit a contact inquiry",
				"description": "Receives a consulting inquiry and emails it to the site owner. Accepts application/json, application/x-www-form-urlencoded, or multipart/form-data bodies up to 20 KB. Browser submissions carry a Cloudflare Turnstile token in the cf-turnstile-response field; submissions without a valid token are rejected with 403 turnstile_failed. Every response carries IETF RateLimit-Policy and RateLimit headers; accepted submissions are limited to 3 per IP per 10 minutes.",
				"requestBody": {
					"required": true,
					"content": {
						"application/json": {
							"schema": {
								"$ref": "#/components/schemas/InquirySubmission"
							}
						},
						"application/x-www-form-urlencoded": {
							"schema": {
								"$ref": "#/components/schemas/InquirySubmission"
							}
						},
						"multipart/form-data": {
							"schema": {
								"$ref": "#/components/schemas/InquirySubmission"
							}
						}
					}
				},
				"responses": {
					"200": {
						"description": "Inquiry accepted for delivery.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"required": [
										"ok"
									],
									"properties": {
										"ok": {
											"type": "boolean",
											"const": true
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Malformed body or failed field validation. validation_failed includes an errors map keyed by field.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/Error"
								}
							}
						}
					},
					"403": {
						"description": "Cross-origin request (origin_forbidden) or missing/invalid Turnstile token (turnstile_failed).",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/Error"
								}
							}
						}
					},
					"405": {
						"description": "Method is not POST. The Allow header lists the supported method.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/Error"
								}
							}
						}
					},
					"413": {
						"description": "Body exceeds 20 KB (payload_too_large).",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/Error"
								}
							}
						}
					},
					"415": {
						"description": "Content-Type is not one of the three supported types (unsupported_media_type).",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/Error"
								}
							}
						}
					},
					"429": {
						"description": "Rate limit exceeded (rate_limited). Retry-After reports the wait in seconds.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/Error"
								}
							}
						}
					},
					"502": {
						"description": "Delivery failed after acceptance (send_failed); retry later.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/Error"
								}
							}
						}
					},
					"503": {
						"description": "Service temporarily unavailable (service_unavailable).",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/Error"
								}
							}
						}
					}
				}
			}
		},
		"/api/inquiry": {
			"post": {
				"operationId": "submitInquiryLegacyAlias",
				"summary": "Submit a contact inquiry (deprecated alias)",
				"description": "Compatibility alias for /api/v1/inquiry with identical behavior; use the versioned path.",
				"deprecated": true,
				"responses": {
					"200": {
						"description": "Inquiry accepted for delivery.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"required": [
										"ok"
									],
									"properties": {
										"ok": {
											"type": "boolean",
											"const": true
										}
									}
								}
							}
						}
					},
					"400": {
						"description": "Malformed body or failed field validation. validation_failed includes an errors map keyed by field.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/Error"
								}
							}
						}
					},
					"403": {
						"description": "Cross-origin request (origin_forbidden) or missing/invalid Turnstile token (turnstile_failed).",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/Error"
								}
							}
						}
					},
					"405": {
						"description": "Method is not POST. The Allow header lists the supported method.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/Error"
								}
							}
						}
					},
					"413": {
						"description": "Body exceeds 20 KB (payload_too_large).",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/Error"
								}
							}
						}
					},
					"415": {
						"description": "Content-Type is not one of the three supported types (unsupported_media_type).",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/Error"
								}
							}
						}
					},
					"429": {
						"description": "Rate limit exceeded (rate_limited). Retry-After reports the wait in seconds.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/Error"
								}
							}
						}
					},
					"502": {
						"description": "Delivery failed after acceptance (send_failed); retry later.",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/Error"
								}
							}
						}
					},
					"503": {
						"description": "Service temporarily unavailable (service_unavailable).",
						"content": {
							"application/json": {
								"schema": {
									"$ref": "#/components/schemas/Error"
								}
							}
						}
					}
				}
			}
		},
		"/.well-known/oauth-protected-resource": {
			"get": {
				"operationId": "getProtectedResourceMetadata",
				"summary": "RFC 9728 protected-resource metadata",
				"description": "Describes the OAuth 2.0 protection of this origin's MCP resource (/_emdash/api/mcp): authorization servers, supported scopes, and bearer methods.",
				"responses": {
					"200": {
						"description": "Protected-resource metadata document.",
						"content": {
							"application/json": {
								"schema": {
									"type": "object",
									"required": [
										"resource",
										"authorization_servers",
										"scopes_supported"
									],
									"properties": {
										"resource": {
											"type": "string",
											"format": "uri",
											"description": "Canonical resource identifier (the MCP endpoint)."
										},
										"authorization_servers": {
											"type": "array",
											"items": {
												"type": "string",
												"format": "uri"
											}
										},
										"scopes_supported": {
											"type": "array",
											"items": {
												"type": "string"
											}
										},
										"bearer_methods_supported": {
											"type": "array",
											"items": {
												"type": "string"
											}
										}
									}
								}
							}
						}
					}
				}
			}
		}
	},
	"components": {
		"schemas": {
			"InquirySubmission": {
				"type": "object",
				"required": [
					"name",
					"email",
					"message"
				],
				"properties": {
					"name": {
						"type": "string",
						"minLength": 2,
						"maxLength": 100,
						"description": "Sender name."
					},
					"email": {
						"type": "string",
						"format": "email",
						"maxLength": 254,
						"description": "Reply-to address."
					},
					"company": {
						"type": "string",
						"maxLength": 120,
						"description": "Optional company name."
					},
					"message": {
						"type": "string",
						"minLength": 20,
						"maxLength": 5000,
						"description": "Inquiry body."
					},
					"aiPrompt": {
						"type": "string",
						"maxLength": 2000,
						"description": "Optional AI referral prompt that led to the inquiry."
					},
					"website": {
						"type": "string",
						"maxLength": 0,
						"description": "Honeypot. Must be omitted or empty; any value silently accepts and discards the submission."
					}
				}
			},
			"Error": {
				"type": "object",
				"required": [
					"ok",
					"code"
				],
				"properties": {
					"ok": {
						"type": "boolean",
						"const": false
					},
					"code": {
						"type": "string",
						"description": "Stable machine-readable error code.",
						"enum": [
							"invalid_request",
							"validation_failed",
							"origin_forbidden",
							"turnstile_failed",
							"method_not_allowed",
							"payload_too_large",
							"unsupported_media_type",
							"rate_limited",
							"send_failed",
							"service_unavailable"
						]
					},
					"message": {
						"type": "string",
						"description": "Human-readable explanation."
					},
					"hint": {
						"type": "string",
						"description": "Resolution hint for callers."
					},
					"errors": {
						"type": "object",
						"additionalProperties": {
							"type": "string"
						},
						"description": "Per-field validation messages; present only on validation_failed."
					}
				}
			}
		}
	}
}