{
  "SuccessCode": "SUCCESS",
  "Protocol": "AIXE",
  "Endpoint": "/aixe/research/complete-contact-research",
  "Method": "POST",
  "ContentType": "application/json",
  "Title": "Complete Contact Research",
  "Description": "Finish one actively claimed person\u0027s focused research in a single transaction. Supply the contact key and current unexpired claim key returned by claim-next-contact. ContactDetails is the complete set found during this research pass and may contain zero to 100 entries. Each entry uses unrestricted free text for its type, so any current or future platform, directory, communication method, biography, or professional source can be represented. Details are saved, the person becomes Completed or Completed \u2014 No Contact Details Found, and the overall search completes automatically after every person reaches a terminal status. Retrying the same completed claim is idempotent and does not duplicate details.",
  "Authentication": "Use the capability credential described in InputFields. Research mutation endpoints use unguessable public record keys as scoped capability credentials; never substitute numeric database IDs.",
  "RequestRules": [
    "Send one JSON object using the exact case-sensitive field names in InputFields.",
    "Required means the property must be present and valid. Omit an optional property when its value is unknown unless that field description explicitly permits null or empty text.",
    "GUID values are JSON strings in standard GUID format. Never send internal numeric database IDs.",
    "A successful HTTP response is not enough by itself; inspect the response body\u0027s SuccessCode."
  ],
  "InputFields": [
    {
      "Name": "SearchRequestContactKey",
      "Type": "guid",
      "Required": true,
      "Description": "Public GUID identifying one person already linked to a search. Obtain it from create-search-contact, list-search-contacts, or claim-next-contact. It is never a numeric database ID."
    },
    {
      "Name": "SearchRequestContactResearchClaimKey",
      "Type": "guid",
      "Required": true,
      "Description": "Temporary claim GUID returned by claim-next-contact. It proves this worker owns the current research lease for this person. A missing, expired, released, completed, or replaced claim is rejected."
    },
    {
      "Name": "ContactDetails",
      "Type": "array\u003Cobject\u003E",
      "Required": true,
      "Description": "JSON array with zero to 100 objects. Each object: ContactDetailType (required free-text label, up to 200 characters), ContactDetailValue (required displayed value, up to 2,000 characters), ContactDetailUrl (optional direct profile/contact URL, up to 2,048 characters), ContactDetailSourceUrl (optional URL where this exact detail was found or confirmed, up to 2,048 characters), ContactDetailNotes (optional context, up to 4,000 characters), and optional SearchRequestContactDetailKey GUID for caller-controlled identity. An empty array explicitly means research completed without finding contact details."
    }
  ],
  "Output": "Data fields: SearchRequestContactKey confirms the completed person; SearchRequestContactResearchStatus becomes Completed when at least one detail was supplied or Completed \u2014 No Contact Details Found for an empty array; SearchRequestContactResearchCompletedDate is the UTC finish time; ContactDetailCount is the number stored by this completion; SearchRequestContactDetailKeys contains the public GUID for each stored detail. An idempotent retry returns the existing total count and does not insert the submitted array again.",
  "OperationalGuidance": [
    "Collect the focused person\u0027s results, then submit them together through this endpoint.",
    "ContactDetailType is intentionally not an enum. Describe the information accurately instead of forcing it into a predefined platform list.",
    "ContactDetailUrl is the contact destination; ContactDetailSourceUrl is the evidence source. They may be the same URL when a public profile is both.",
    "Do not put details for multiple people in one completion call."
  ],
  "ResponseEnvelope": [
    {
      "Name": "SuccessCode",
      "Type": "string",
      "Required": true,
      "Description": "SUCCESS means the operation completed. Any other value is a machine-readable error code and means the requested change or read did not complete as described."
    },
    {
      "Name": "Message",
      "Type": "string",
      "Required": true,
      "Description": "Human-readable outcome and next-step context. Use SuccessCode for program decisions."
    },
    {
      "Name": "Data",
      "Type": "object|null",
      "Required": false,
      "Description": "Endpoint-specific result described by Output. Error responses may omit this property or return null."
    },
    {
      "Name": "PersonAuthenticationTokenExpiration",
      "Type": "datetime|null",
      "Required": false,
      "Description": "Returned by authenticated customer calls after a successful sliding-session refresh. Research endpoints do not use or return it."
    }
  ],
  "Errors": [
    "VALIDATION_FAILED",
    "AUTHENTICATION_REQUIRED",
    "AUTHENTICATION_FAILED",
    "NOT_FOUND",
    "ACCESS_DENIED",
    "ACCOUNT_EXISTS",
    "CONFLICT",
    "NOT_SUPPORTED",
    "REJECTED",
    "RATE_LIMITED",
    "INSUFFICIENT_CREDITS",
    "CONFIGURATION_REQUIRED",
    "FAILED"
  ]
}