{
  "openapi": "3.1.0",
  "info": {
    "title": "Anatomy IT website API",
    "version": "1.0.0",
    "summary": "The HTTP endpoints www.anatomyit.com offers to AI agents and other programs.",
    "description": "Reading the site needs no credentials: every page has a Markdown twin (add `.md` to its address, or send `Accept: text/markdown`), and `/llms.txt` indexes them. The one write capability is submitting a contact request on behalf of a real person. A registered agent gets a Bearer token from `/api/agent/token` and sends it to `/api/lead/contact`. Registration is reviewed by a person, not self-serve: see https://www.anatomyit.com/auth.md. The same two capabilities are also offered over MCP at `/mcp` and A2A at `/a2a`; `/.well-known/api-catalog` lists everything.",
    "contact": {
      "name": "Anatomy IT",
      "url": "https://www.anatomyit.com/contact"
    }
  },
  "externalDocs": {
    "description": "Agent registration and how to use a token",
    "url": "https://www.anatomyit.com/auth.md"
  },
  "servers": [
    {
      "url": "https://www.anatomyit.com"
    }
  ],
  "tags": [
    {
      "name": "auth",
      "description": "Getting a token as a registered agent"
    },
    {
      "name": "leads",
      "description": "Submitting a contact request"
    }
  ],
  "paths": {
    "/api/agent/token": {
      "post": {
        "tags": [
          "auth"
        ],
        "operationId": "issueAgentToken",
        "summary": "Get a Bearer token (OAuth 2.0 Client Credentials)",
        "description": "For registered agents only. The token is good for one hour and carries the scope `leads:write`. Discovery metadata: `/.well-known/oauth-authorization-server`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "grant_type",
                  "client_id",
                  "client_secret"
                ],
                "properties": {
                  "grant_type": {
                    "type": "string",
                    "enum": [
                      "client_credentials"
                    ]
                  },
                  "client_id": {
                    "type": "string"
                  },
                  "client_secret": {
                    "type": "string"
                  },
                  "scope": {
                    "type": "string",
                    "description": "Optional. `leads:write` is the only scope."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The token.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenResponse"
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request`, `unsupported_grant_type` or `invalid_scope`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAuthError"
                }
              }
            }
          },
          "401": {
            "description": "`invalid_client`: unknown client or wrong secret.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAuthError"
                }
              }
            }
          },
          "503": {
            "description": "`not_configured`: this deployment does not issue tokens.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OAuthError"
                }
              }
            }
          }
        }
      }
    },
    "/api/lead/contact": {
      "post": {
        "tags": [
          "leads"
        ],
        "operationId": "submitContactRequest",
        "summary": "Submit a contact request",
        "description": "Sends a contact request to Anatomy IT, the same one the form on https://www.anatomyit.com/contact sends. A registered agent authenticates with `Authorization: Bearer <token>`. Without a Bearer token the request must carry a Cloudflare Turnstile token in `turnstileToken`, which only a browser on the contact page can obtain. Every field is validated the same way either way. A value longer than its limit is cut to the limit, not refused; the only length that is refused is a phone number under 7 characters.",
        "security": [
          {
            "agentToken": [
              "leads:write"
            ]
          },
          {}
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactRequest"
              },
              "example": {
                "fields": {
                  "firstname": "Jordan",
                  "lastname": "Rivera",
                  "email": "jordan.rivera@example.com",
                  "state_name": "NY",
                  "company": "Example Medical Group",
                  "reason_for_inquiry": "Sales",
                  "message": "We are a 40-provider practice looking for managed IT and HIPAA support."
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The request was accepted.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "message"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request could not be read, or a field failed validation. `error` is `Send application/json` (wrong content type), `Invalid JSON`, `Send a JSON object`, or `invalid_fields` (with one message per field in `fieldErrors`, or a general `message`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadError"
                }
              }
            }
          },
          "401": {
            "description": "`invalid_token`: the Bearer token is missing a required claim, expired or not valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadError"
                }
              }
            }
          },
          "403": {
            "description": "`challenge_failed`: no Bearer token was sent and the Turnstile check did not pass. `codes` carries the reasons Turnstile gave.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadError"
                }
              }
            }
          },
          "502": {
            "description": "`upstream_unreachable` or `upstream_error`: the request could not be passed on. Safe to try again.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadError"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "agentToken": {
        "type": "oauth2",
        "description": "OAuth 2.0 Client Credentials for registered agents. See https://www.anatomyit.com/auth.md.",
        "flows": {
          "clientCredentials": {
            "tokenUrl": "https://www.anatomyit.com/api/agent/token",
            "scopes": {
              "leads:write": "Submit a contact request on a person's behalf"
            }
          }
        }
      }
    },
    "schemas": {
      "ContactRequest": {
        "type": "object",
        "required": [
          "fields"
        ],
        "properties": {
          "fields": {
            "type": "object",
            "required": [
              "firstname",
              "lastname",
              "email",
              "state_name",
              "reason_for_inquiry"
            ],
            "properties": {
              "firstname": {
                "type": "string",
                "description": "First name",
                "maxLength": 500
              },
              "lastname": {
                "type": "string",
                "description": "Last name",
                "maxLength": 500
              },
              "email": {
                "type": "string",
                "format": "email",
                "description": "Business email",
                "maxLength": 500
              },
              "state_name": {
                "type": "string",
                "description": "US state, as its two-letter postal code",
                "enum": [
                  "AL",
                  "AK",
                  "AZ",
                  "AR",
                  "CA",
                  "CO",
                  "CT",
                  "DE",
                  "FL",
                  "GA",
                  "HI",
                  "ID",
                  "IL",
                  "IN",
                  "IA",
                  "KS",
                  "KY",
                  "LA",
                  "ME",
                  "MD",
                  "MA",
                  "MI",
                  "MN",
                  "MS",
                  "MO",
                  "MT",
                  "NE",
                  "NV",
                  "NH",
                  "NJ",
                  "NM",
                  "NY",
                  "NC",
                  "ND",
                  "OH",
                  "OK",
                  "OR",
                  "PA",
                  "RI",
                  "SC",
                  "SD",
                  "TN",
                  "TX",
                  "UT",
                  "VT",
                  "VA",
                  "WA",
                  "WV",
                  "WI",
                  "WY"
                ]
              },
              "phone": {
                "type": "string",
                "minLength": 7,
                "maxLength": 20,
                "description": "Best number to reach the person. Under 7 characters is refused; anything past 20 is cut off."
              },
              "company": {
                "type": "string",
                "description": "Company name",
                "maxLength": 500
              },
              "jobtitle": {
                "type": "string",
                "description": "The person's title",
                "maxLength": 500
              },
              "reason_for_inquiry": {
                "type": "string",
                "enum": [
                  "General",
                  "Sales",
                  "Partner",
                  "Media"
                ]
              },
              "how_did_you_heart_about_us": {
                "type": "string",
                "description": "How the person heard about Anatomy IT. The field name is spelled this way on purpose: it is the name the receiving system uses.",
                "enum": [
                  "Referral",
                  "Webinar",
                  "Event",
                  "Social",
                  "News Story",
                  "Online Search"
                ]
              },
              "message": {
                "type": "string",
                "maxLength": 2000,
                "description": "How Anatomy IT can help. Anything past 2000 characters is cut off."
              }
            }
          },
          "turnstileToken": {
            "type": "string",
            "description": "Browser submissions only. Not needed with a Bearer token."
          },
          "attribution": {
            "type": "object",
            "description": "Optional, sent by the site's own form: the campaign parameters the person arrived with. An agent can leave it out.",
            "properties": {
              "utm_source": {
                "type": "string"
              },
              "utm_medium": {
                "type": "string"
              },
              "utm_campaign": {
                "type": "string"
              },
              "utm_term": {
                "type": "string"
              },
              "utm_content": {
                "type": "string"
              },
              "gclid": {
                "type": "string"
              },
              "fbclid": {
                "type": "string"
              },
              "msclkid": {
                "type": "string"
              },
              "li_fat_id": {
                "type": "string"
              }
            }
          }
        }
      },
      "TokenResponse": {
        "type": "object",
        "required": [
          "access_token",
          "token_type",
          "expires_in",
          "scope"
        ],
        "properties": {
          "access_token": {
            "type": "string"
          },
          "token_type": {
            "type": "string",
            "const": "Bearer"
          },
          "expires_in": {
            "type": "integer",
            "description": "Lifetime in seconds"
          },
          "scope": {
            "type": "string"
          }
        }
      },
      "OAuthError": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string"
          },
          "error_description": {
            "type": "string"
          }
        }
      },
      "LeadError": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "fieldErrors": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "codes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Only with `challenge_failed`."
          }
        }
      }
    }
  }
}
