{
  "Protocol": "AIXE",
  "Version": "1.0",
  "Endpoint": "/aixe/quote/submit-quote",
  "Purpose": "Submit or update the authenticated Pro's quote for an open, matched RFQ.",
  "Method": "POST",
  "ContentType": "application/json",
  "DiscoveryRequest": "GET /aixe/quote/submit-quote/?",
  "RequiredFields": {
    "PersonAuthenticationToken": "Unexpired login token. It determines the Pro; renews to now plus 15 minutes UTC.",
    "RFQKey": "Public GUID of the RFQ to quote. Obtain from available AIXE capabilities or user-provided context; never invent it.",
    "Amount": "JSON number in USD from 0.01 through 10000000 inclusive, with at most two decimal places.",
    "Type": "Exactly Estimate, Fixed Price, or Hourly. For Hourly, Amount is the hourly rate.",
    "Description": "Nonblank scope of work, up to 4000 characters. Ask for the intended price, type, and scope; do not invent commercial terms."
  },
  "OptionalFields": {
    "Availability": "Proposed availability, up to 150 characters. Omitted or null becomes empty; this also clears previous availability on update."
  },
  "BusinessRules": [
    "Public access still requires a valid token. If configured Private, the token-derived PersonID must additionally have an AIXEEndpointAccess Linker grant. No SupervisorPersonKey is used.",
    "Only an Open RFQ with an eligible, non-hidden RFQMatch for this Person accepts a quote. The project owner cannot quote their own RFQ. Unknown or inaccessible RFQs return QUOTE_NOT_ALLOWED without disclosing their details.",
    "Identity comes only from the token. Submitted PersonID, PersonKey, QuoteKey, QuoteStatus, internal IDs, and Linker fields cannot override identity or server-controlled fields.",
    "The Quote record and RFQMatch-to-Quote Linker with role Quote commit together in one serializable transaction. The match identifies both the Pro and RFQ. No separate category Linker is needed on the quote.",
    "There is one quote per Pro match. The first successful call creates it with status Submitted. Subsequent calls replace Amount, Type, Description, and Availability on that same quote, preserving its key, status, creation date, and conversation links. Created distinguishes creation from update.",
    "Text is trimmed. Amounts with more than two nonzero decimal places are rejected rather than rounded. Success returns stored quote fields, public keys, and refreshed expiration; no numeric IDs, passwords, or token value.",
    "The project-owner quote email uses the existing immediate notification path after the transaction commits. NotificationAccepted reports SMTP acceptance, not inbox delivery. A false value does not undo the quote and is not queued for automatic retry. Background RFQ match notifications are a separate workflow.",
    "Do not resubmit merely because email failed, or automatically repeat after a timeout or uncertain result. Repeating can overwrite terms and send another email. Report uncertainty; an intentional update must contain all desired quote fields.",
    "This endpoint does not list RFQ matches, read RFQ details, accept/select a quote, withdraw a quote, or send conversation messages. If a needed capability is absent from /aixe.ai and authorized private discovery, stop and report it. Never use the human website interface as a fallback.",
    "Send exact-case JSON properties in the body over HTTPS, never tokens in URLs. Body limit is 16 KiB. GET discovery does not execute or renew authentication."
  ],
  "SuccessfulResponseFields": [
    "SuccessCode",
    "PersonKey",
    "PersonAuthenticationTokenExpiration",
    "Created",
    "RFQKey",
    "Quote",
    "NotificationAccepted",
    "Message"
  ],
  "QuoteFields": [
    "QuoteKey",
    "CreationDate",
    "QuoteUpdatedDate",
    "QuoteAmount",
    "QuoteType",
    "QuoteDescription",
    "QuoteAvailability",
    "QuoteStatus"
  ],
  "Errors": [
    "AUTHENTICATION_REQUIRED",
    "REJECTED",
    "VALIDATION_FAILED",
    "QUOTE_NOT_ALLOWED",
    "CONFLICT",
    "REQUEST_TOO_LARGE",
    "FAILED",
    "WORKFLOW_DISCOVERY_FAILED"
  ],
  "ActionResponse": {
    "OutcomeField": "SuccessCode",
    "SuccessValue": "SUCCESS",
    "Rule": "Only SUCCESS confirms a saved quote. Created indicates new versus updated; NotificationAccepted is a separate email outcome. CONFLICT means this transaction rolled back. Surface FAILED or an uncertain response rather than automatically resubmitting."
  },
  "DocumentationSource": "AIXEEndpointRegistry",
  "AccessType": "Public",
  "ActionRequest": "POST /aixe/quote/submit-quote",
  "CanonicalHelpTrigger": "GET /aixe/quote/submit-quote/?"
}