{
  "openapi": "3.1.0",
  "info": {
    "title": "GTMMCPs company submissions",
    "version": "1.0.0",
    "description": "Private intake, DNS verification and correction API. An agent should submit only with company authorization. Request bodies require application/json and must not exceed 16 KB. Receipt-authorized operations can reveal status and permit requested corrections. There is no public approval or publication endpoint. Automated email and unattended review are not active. Use the hosted discovery MCP separately to search public tools."
  },
  "servers": [
    {
      "url": "https://gtmmcps.com"
    }
  ],
  "paths": {
    "/api/submissions": {
      "post": {
        "operationId": "submitTool",
        "summary": "Submit a tool for research",
        "description": "Creates a private submission; does not publish, send email, or verify claims. Save the returned receipt securely: it is not recoverable through this API. Limit: 5 submissions per UTC day per IP. Matching product/company/contact submissions within 24 hours return 409.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Submission"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Request succeeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Created"
                }
              }
            }
          },
          "400": {
            "description": "Invalid JSON, fields, receipt format, or request larger than 16 KB.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Browser Origin does not match the request origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Daily per-IP request limit reached. Retry on a later UTC day.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Storage, configuration or verification service unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "These product and contact details were submitted within the last 24 hours.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/submissions/status": {
      "post": {
        "operationId": "getSubmissionStatus",
        "summary": "Read a private submission status",
        "description": "Provide the receipt in the JSON body. No contact email or receipt hash is returned. revision_fields appears only when status is needs-changes. Status and verification share a 60-request daily per-IP limit.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReceiptRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Request succeeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Status"
                }
              }
            }
          },
          "400": {
            "description": "Invalid JSON, fields, receipt format, or request larger than 16 KB.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Browser Origin does not match the request origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Daily per-IP request limit reached. Retry on a later UTC day.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Storage, configuration or verification service unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Receipt not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/submissions/verify": {
      "post": {
        "operationId": "verifySubmissionDomain",
        "summary": "Check the company DNS TXT challenge",
        "description": "The company must add the exact record_name and record_value from verification. This endpoint reads DNS only; it does not change DNS. Exact hostname control moves an awaiting-verification submission to awaiting-source-review. It does not verify contact email, MCP ownership or product claims. DNS propagation may require a later retry.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReceiptRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Request succeeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Status"
                }
              }
            }
          },
          "400": {
            "description": "Invalid JSON, fields, receipt format, or request larger than 16 KB.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Browser Origin does not match the request origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Daily per-IP request limit reached. Retry on a later UTC day.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Storage, configuration or verification service unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Receipt not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Submission is not awaiting verification.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Matching TXT record is not visible.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/submissions/revise": {
      "post": {
        "operationId": "reviseSubmission",
        "summary": "Correct a submission after review",
        "description": "Only a DNS-verified needs-changes submission can be revised. Copy expected_updated_at from the latest status. Company identity and contact fields cannot be changed. Saves claim history and returns to awaiting-source-review; does not publish. Limit: 5 revision requests per UTC day per IP.",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Revision"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Request succeeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Status"
                }
              }
            }
          },
          "400": {
            "description": "Invalid JSON, fields, receipt format, or request larger than 16 KB.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Browser Origin does not match the request origin.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Daily per-IP request limit reached. Retry on a later UTC day.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Storage, configuration or verification service unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Receipt not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "State or timestamp changed, or revision could not be saved. Reload status before retrying.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Submission": {
        "type": "object",
        "properties": {
          "product_name": {
            "type": "string",
            "minLength": 2,
            "maxLength": 120
          },
          "company_url": {
            "type": "string",
            "format": "uri",
            "pattern": "^https://",
            "maxLength": 1000,
            "description": "Public HTTPS URL, without credentials, explicit port, local hostname or IP address."
          },
          "contact_email": {
            "type": "string",
            "format": "email",
            "maxLength": 254
          },
          "description": {
            "type": "string",
            "minLength": 30,
            "maxLength": 3000
          },
          "documentation_url": {
            "type": "string",
            "format": "uri",
            "pattern": "^https://",
            "maxLength": 2000,
            "description": "Public HTTPS URL, without credentials, explicit port, local hostname or IP address."
          },
          "mcp_status": {
            "type": "string",
            "enum": [
              "official",
              "community",
              "none",
              "unknown"
            ]
          },
          "mcp_url": {
            "anyOf": [
              {
                "type": "string",
                "format": "uri",
                "pattern": "^https://",
                "maxLength": 2000,
                "description": "Public HTTPS URL, without credentials, explicit port, local hostname or IP address."
              },
              {
                "const": ""
              },
              {
                "type": "null"
              }
            ]
          },
          "consent": {
            "const": true,
            "description": "The submitting company authorizes review of these public details."
          }
        },
        "required": [
          "product_name",
          "company_url",
          "contact_email",
          "description",
          "documentation_url",
          "mcp_status",
          "consent"
        ]
      },
      "ReceiptRequest": {
        "type": "object",
        "properties": {
          "receipt": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$",
            "description": "Private bearer receipt returned once at creation. Keep it out of URLs, logs and public output."
          }
        },
        "required": [
          "receipt"
        ]
      },
      "Revision": {
        "type": "object",
        "properties": {
          "receipt": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$",
            "description": "Private bearer receipt returned once at creation. Keep it out of URLs, logs and public output."
          },
          "expected_updated_at": {
            "type": "string",
            "description": "Copy updated_at exactly from the latest status response."
          },
          "description": {
            "type": "string",
            "minLength": 30,
            "maxLength": 3000
          },
          "documentation_url": {
            "type": "string",
            "format": "uri",
            "pattern": "^https://",
            "maxLength": 2000,
            "description": "Public HTTPS URL, without credentials, explicit port, local hostname or IP address."
          },
          "mcp_status": {
            "type": "string",
            "enum": [
              "official",
              "community",
              "none",
              "unknown"
            ]
          },
          "mcp_url": {
            "anyOf": [
              {
                "type": "string",
                "format": "uri",
                "pattern": "^https://",
                "maxLength": 2000,
                "description": "Public HTTPS URL, without credentials, explicit port, local hostname or IP address."
              },
              {
                "const": ""
              },
              {
                "type": "null"
              }
            ]
          },
          "consent": {
            "const": true,
            "description": "The submitting company authorizes review of these public details."
          }
        },
        "required": [
          "receipt",
          "expected_updated_at",
          "description",
          "documentation_url",
          "mcp_status",
          "consent"
        ],
        "additionalProperties": false
      },
      "Verification": {
        "type": "object",
        "properties": {
          "domain": {
            "type": "string"
          },
          "record_name": {
            "type": "string"
          },
          "record_value": {
            "type": "string",
            "description": "Public DNS TXT challenge; this is not the private receipt."
          },
          "verified_at": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "domain",
          "record_name",
          "record_value",
          "verified_at"
        ]
      },
      "Status": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "description": "Lifecycle state, such as awaiting-verification, awaiting-source-review, needs-changes, requires-owner-review, approved-for-publication or internal-test-archived. Approval is not publication."
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          },
          "review_reason": {
            "type": "string"
          },
          "email_status": {
            "type": "string"
          },
          "verification": {
            "$ref": "#/components/schemas/Verification"
          },
          "revision_fields": {
            "type": "object",
            "properties": {
              "description": {
                "type": "string",
                "minLength": 30,
                "maxLength": 3000
              },
              "documentation_url": {
                "type": "string",
                "format": "uri",
                "pattern": "^https://",
                "maxLength": 2000,
                "description": "Public HTTPS URL, without credentials, explicit port, local hostname or IP address."
              },
              "mcp_status": {
                "type": "string",
                "enum": [
                  "official",
                  "community",
                  "none",
                  "unknown"
                ]
              },
              "mcp_url": {
                "anyOf": [
                  {
                    "type": "string",
                    "format": "uri",
                    "pattern": "^https://",
                    "maxLength": 2000,
                    "description": "Public HTTPS URL, without credentials, explicit port, local hostname or IP address."
                  },
                  {
                    "const": ""
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "required": [
              "description",
              "documentation_url",
              "mcp_status",
              "mcp_url"
            ]
          },
          "published_url": {
            "type": "string",
            "format": "uri",
            "pattern": "^https://gtmmcps\\.com/tools/[a-z0-9][a-z0-9-]{0,150}$",
            "description": "Present only for a published submission with a verified catalog publication record."
          }
        },
        "required": [
          "id",
          "status",
          "created_at",
          "updated_at",
          "review_reason",
          "email_status",
          "verification"
        ]
      },
      "Created": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "receipt": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$",
            "description": "Private bearer receipt returned once at creation. Keep it out of URLs, logs and public output."
          },
          "status": {
            "const": "awaiting-verification"
          },
          "email_status": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "verification": {
            "$ref": "#/components/schemas/Verification"
          }
        },
        "required": [
          "id",
          "receipt",
          "status",
          "email_status",
          "message",
          "verification"
        ]
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          }
        },
        "required": [
          "error"
        ]
      }
    }
  }
}
