{
  "openapi": "3.1.0",
  "info": {
    "title": "Kestrel early-access API",
    "version": "1.0.0",
    "summary": "Request early access to Kestrel, an AI-native consulting firm in St. Louis, for a person.",
    "description": "Kestrel deploys an AI agent inside the software a company already uses to find repetitive work and automate it. The agent is in development and has no public API yet.\n\nThis API has one operation: an early-access request, the same one the form on meetkestrel.com sends. The founders read every request and reply to the person by email.\n\nSend a request only for a person who asked you to, with their real name and email address. Send it once, and reuse the same requestId if you retry: a request is never sent twice.\n\nThere is no API key. One network address can send 8 requests an hour.",
    "contact": {
      "name": "Kestrel",
      "email": "hello@meetkestrel.com",
      "url": "https://meetkestrel.com/developers"
    }
  },
  "externalDocs": {
    "description": "For AI agents and developers",
    "url": "https://meetkestrel.com/developers"
  },
  "servers": [
    {
      "url": "https://meetkestrel.com"
    }
  ],
  "security": [],
  "tags": [
    {
      "name": "Early access",
      "description": "Ask the founders for early access to Kestrel's agent."
    }
  ],
  "paths": {
    "/api/contact": {
      "post": {
        "operationId": "requestEarlyAccess",
        "tags": [
          "Early access"
        ],
        "summary": "Request early access for a person",
        "description": "Sends a person's early-access request to Kestrel's founders by email. Use it only when the person asked you to. A 201 or 200 response means the request was sent; it doesn't book a meeting or confirm early access.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EarlyAccessRequest"
              },
              "examples": {
                "assistant": {
                  "summary": "An AI assistant asking for a person",
                  "value": {
                    "name": "Jordan Ellis",
                    "email": "jordan@example.com",
                    "company": "Gateway Supply Co.",
                    "message": "Tools: NetSuite\n\nWe retype about 40 emailed purchase orders a week.",
                    "requestId": "0b7f8c1e-3d2a-4f5b-9c6d-7e8f9a0b1c2d",
                    "source": "ai"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A repeat of a request already sent (same requestId and details). It was not sent again.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Receipt"
                }
              }
            }
          },
          "201": {
            "description": "The request was sent to the founders.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Receipt"
                }
              }
            }
          },
          "400": {
            "description": "The request couldn't be read or is missing something. Codes: `invalid_body`, `invalid_field`, `rejected`, `invalid_request_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "A browser sent the request from another website. Codes: `origin_rejected`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "This requestId was already sent with different details. Codes: `request_changed`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "One or more fields are invalid; `errors` lists them. Codes: `validation_failed`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests from this address. Codes: `rate_limited`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before trying again.",
                "schema": {
                  "type": "integer",
                  "example": 3600
                }
              }
            }
          },
          "503": {
            "description": "The request couldn't be sent right now. Retry with the same requestId. Codes: `unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "description": "Seconds to wait before trying again.",
                "schema": {
                  "type": "integer",
                  "example": 60
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "EarlyAccessRequest": {
        "type": "object",
        "required": [
          "name",
          "email",
          "company",
          "message",
          "requestId"
        ],
        "additionalProperties": false,
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "description": "The person's name."
          },
          "email": {
            "type": "string",
            "format": "email",
            "maxLength": 254,
            "description": "The person's email address. The founders reply here."
          },
          "company": {
            "type": "string",
            "maxLength": 160,
            "description": "The person's company. Send an empty string if there's none."
          },
          "message": {
            "type": "string",
            "maxLength": 3000,
            "description": "What they'd like to automate. To list their software, start with a line like `Tools: NetSuite, Microsoft 365`, then a blank line. Send an empty string if there's nothing to add."
          },
          "requestId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$",
            "description": "A random UUID (version 4) that identifies this request. Reuse it if you retry; a request is never sent twice."
          },
          "source": {
            "type": "string",
            "enum": [
              "direct",
              "search",
              "ai",
              "linkedin",
              "email",
              "referral",
              "other"
            ],
            "default": "other",
            "description": "How the request started. Use `ai` for an AI assistant."
          },
          "landing": {
            "type": "string",
            "pattern": "^/[a-z0-9\\-/]{0,100}$",
            "description": "Optional. The first page of the person's visit, if they visited the site."
          },
          "page": {
            "type": "string",
            "pattern": "^/[a-z0-9\\-/]{0,100}$",
            "description": "Optional. The page the request was sent from."
          },
          "website": {
            "type": "string",
            "maxLength": 0,
            "description": "Leave this out or empty. It's a trap for spam bots; anything in it rejects the request."
          }
        }
      },
      "Receipt": {
        "type": "object",
        "required": [
          "ok",
          "receipt"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "receipt": {
            "type": "string",
            "format": "uuid",
            "description": "The requestId, as the reference for this request."
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "error",
          "code",
          "hint",
          "docs"
        ],
        "properties": {
          "error": {
            "type": "string",
            "description": "What went wrong, in a sentence for people."
          },
          "code": {
            "type": "string",
            "enum": [
              "invalid_body",
              "invalid_field",
              "rejected",
              "invalid_request_id",
              "origin_rejected",
              "validation_failed",
              "request_changed",
              "rate_limited",
              "unavailable",
              "not_found",
              "method_not_allowed"
            ],
            "description": "A stable code for programs."
          },
          "hint": {
            "type": "string",
            "description": "What to do about it."
          },
          "docs": {
            "type": "string",
            "format": "uri",
            "description": "Where the errors are documented."
          },
          "field": {
            "type": "string",
            "description": "For invalid_field: the field that wasn't a string."
          },
          "errors": {
            "type": "object",
            "description": "For validation_failed: a message for each invalid field.",
            "properties": {
              "name": {
                "type": "string"
              },
              "email": {
                "type": "string"
              },
              "company": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            },
            "additionalProperties": false
          }
        }
      }
    }
  }
}
