{
  "Protocol": "AIXE",
  "Version": "1.0",
  "Endpoint": "/aixe/rfq/create-rfq",
  "Purpose": "Create an RFQ owned by the authenticated Person, link it to one active category, and match eligible professionals.",
  "Method": "POST",
  "ContentType": "application/json; charset=utf-8",
  "DiscoveryRequest": "GET /aixe/rfq/create-rfq/?",
  "RequiredFields": {
    "PersonAuthenticationToken": "Valid unexpired token from registration or login.",
    "Title": "Project title, 5\u2013150 characters after trimming.",
    "Description": "Project details, 20\u20136000 characters after trimming.",
    "Timing": "One of ASAP, Within A Few Days, Within A Week, Within A Month, Flexible.",
    "Address": "Job street address, 1\u2013200 characters.",
    "City": "Job city, 1\u2013100 characters.",
    "State": "Two-letter state abbreviation.",
    "Zip": "Five-digit ZIP present in the site ZIP directory."
  },
  "RequiredOneOf": {
    "Fields": [
      "CategoryKey",
      "Category"
    ],
    "Rule": "Supply exactly one: CategoryKey from the category list, or Category containing the complete standalone category name. Do not send both."
  },
  "OptionalFields": {
    "CategoryKey": "Public GUID for one active category; required when Category is omitted.",
    "Category": "Complete active category name, maximum 100 characters; required when CategoryKey is omitted. Name matching ignores case and surrounding whitespace.",
    "Address2": "Optional additional address details, maximum 100 characters."
  },
  "BusinessRules": [
    "This action requires a valid token. Public access does not waive authentication; private access, if configured, additionally requires the normal AIXEEndpointAccess grant. Authorized calls renew expiration to now plus 15 minutes UTC.",
    "The token identifies the owner. Caller-supplied PersonID, PersonKey, SupervisorPersonKey, RFQKey, RFQID, status, and Linker details cannot override ownership or server-generated fields.",
    "Exactly one active category must resolve. CategoryKey is preferred and should be obtained from the category directory discovered through /aixe.ai. A Category name must match a whole name, not a description, group, slug, partial match, list, or hierarchy.",
    "Category names are not necessarily unique. CATEGORY_AMBIGUOUS requires a CategoryKey from the category directory; CATEGORY_NOT_AVAILABLE means no active category matched. Neither creates an RFQ or a new category.",
    "Creation is atomic: one Open RFQ, a Person-to-RFQ Linker with role Owner, and one Category-to-RFQ Linker with role Category. Both Linkers commit with the RFQ or the transaction rolls back.",
    "All required text must be nonblank. Fields are trimmed and State is uppercased. Supply the actual job address; do not assume it is the person\u0027s profile address unless they have indicated that location.",
    "After saving, existing marketplace matching finds eligible Pros by category and travel radius and excludes the owner from their own project. Required match notifications are recorded with the matches and delivered separately by the background worker.",
    "SUCCESS confirms the saved change. MatchingCompleted and NotificationsQueued are true when matching finished and any required notifications are durably represented by unsent RFQMatch rows. NotificationDelivery is Background. Queued does not mean SMTP delivery has happened; when matching fails, some notification work may already exist.",
    "Each successful create call creates a new RFQ. Do not repeat after SUCCESS, a timeout, or an uncertain result; report the issue instead of risking a duplicate. Preserve the returned RFQKey.",
    "The response returns the created RFQ details, CategoryKey, and CategoryName to its owner, with no numeric IDs or token value. Street addresses continue to follow existing marketplace visibility rules for other people.",
    "Photo upload and RFQ editing/deletion are not supported by this action. If a needed capability is absent from /aixe.ai or authorized private discovery, stop and report the missing AIXE capability. Never fall back to the human website interface.",
    "Send exact-case JSON properties in the request body over HTTPS, never put tokens in URLs. Maximum body size is 16 KiB. GET discovery returns these instructions without creating a record or renewing a token.",
    "Match notification email is sent by a separate background worker after the request. Failed sends retry after one minute; interrupted claims become available after two minutes. Pending work survives application restarts. Existing quotes, conversations, and hidden-match history are preserved."
  ],
  "SuccessfulResponseFields": [
    "SuccessCode",
    "PersonKey",
    "PersonAuthenticationTokenExpiration",
    "RFQ",
    "MatchingCompleted",
    "Message",
    "NotificationsQueued",
    "NotificationDelivery"
  ],
  "RFQFields": [
    "RFQKey",
    "CreationDate",
    "RFQUpdatedDate",
    "RFQTitle",
    "RFQDescription",
    "RFQTiming",
    "RFQStatus",
    "CategoryKey",
    "CategoryName",
    "RFQAddress",
    "RFQAddress2",
    "RFQCity",
    "RFQState",
    "RFQZip"
  ],
  "Errors": [
    "AUTHENTICATION_REQUIRED",
    "REJECTED",
    "VALIDATION_FAILED",
    "CATEGORY_NOT_AVAILABLE",
    "CATEGORY_AMBIGUOUS",
    "REQUEST_TOO_LARGE",
    "FAILED",
    "WORKFLOW_DISCOVERY_FAILED"
  ],
  "ActionResponse": {
    "OutcomeField": "SuccessCode",
    "SuccessValue": "SUCCESS",
    "Rule": "Only SUCCESS confirms the saved change. MatchingCompleted and NotificationsQueued describe matching and queued notification work, not delivery. Match email is processed separately. Never repeat RFQ creation because an email has not arrived."
  },
  "DocumentationSource": "AIXEEndpointRegistry",
  "AccessType": "Public",
  "ActionRequest": "POST /aixe/rfq/create-rfq",
  "CanonicalHelpTrigger": "GET /aixe/rfq/create-rfq/?"
}