> ## Documentation Index
> Fetch the complete documentation index at: https://developers.hubspot.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

---
id: f39e2aac-9d1c-4cff-b3a4-5d0dc99fa88f
---

# CRM API | Goals

> Goals are used to create user-specific quotas for their sales and services teams based on templates provided by HubSpot. The goals endpoints allow you to sync this data between HubSpot and other systems. 

export const Property = ({name, label, type, fieldType, description, required = false, searchable = false, primaryDisplayProperty = false, secondaryDisplayProperty = false, options = null, expanded = true, json = null}) => {
  return null;
};

export const PropertyDefinitions = ({searchable = true, placeholder = "Search properties", objectPluralName = "Records", compact = true, children}) => {
  const fieldTypeConfigs = {
    text: {
      label: 'Single-line text'
    },
    textarea: {
      label: 'Multi-line text'
    },
    phonenumber: {
      label: 'Phone number'
    },
    booleancheckbox: {
      label: 'Single checkbox'
    },
    checkbox: {
      label: 'Multiple checkboxes'
    },
    select: {
      label: 'Dropdown select'
    },
    radio: {
      label: 'Radio select'
    },
    date: {
      label: 'Date picker'
    },
    datetime: {
      label: 'Date and time picker'
    },
    number: {
      label: 'Number'
    },
    calculation_equation: {
      label: 'Equation'
    },
    calculation_rollup: {
      label: 'Rollup'
    }
  };
  const formatDataType = type => {
    const formatted = type.replace(/_/g, ' ');
    return formatted.charAt(0).toUpperCase() + formatted.slice(1);
  };
  const handleDropdownOptionKeyDown = (e, closeDropdown) => {
    if (e.key === 'Escape') {
      e.preventDefault();
      closeDropdown();
      e.currentTarget.closest('.property-type-filter, .property-field-type-filter')?.querySelector('.property-type-filter-button')?.focus();
    } else if (e.key === 'ArrowDown') {
      e.preventDefault();
      const nextOption = e.currentTarget.nextElementSibling;
      if (nextOption) {
        nextOption.focus();
      } else {
        const firstOption = e.currentTarget.parentElement?.querySelector('button');
        firstOption?.focus();
      }
    } else if (e.key === 'ArrowUp') {
      e.preventDefault();
      const prevOption = e.currentTarget.previousElementSibling;
      if (prevOption) {
        prevOption.focus();
      } else {
        const opts = e.currentTarget.parentElement?.querySelectorAll('button');
        opts?.[opts.length - 1]?.focus();
      }
    }
  };
  const FilterDropdown = ({containerClassName, value, isOpen, onToggle, onSelect, allLabel, options, formatLabel}) => <div className={containerClassName}>
      <button onClick={onToggle} onKeyDown={e => {
    if (e.key === 'Escape' && isOpen) {
      e.preventDefault();
      onToggle();
    } else if (e.key === 'ArrowDown') {
      e.preventDefault();
      if (!isOpen) {
        onToggle();
      } else {
        const dropdown = e.currentTarget.nextElementSibling;
        dropdown?.querySelector('button')?.focus();
      }
    } else if (e.key === 'ArrowUp' && isOpen) {
      e.preventDefault();
      const dropdown = e.currentTarget.nextElementSibling;
      const opts = dropdown?.querySelectorAll('button');
      opts?.[opts.length - 1]?.focus();
    }
  }} className="property-type-filter-button" aria-expanded={isOpen} aria-haspopup="true" type="button">
        <span>{value === 'all' ? allLabel : formatLabel ? formatLabel(value) : value}</span>
        <span className="dropdown-caret" aria-hidden="true" />
      </button>

      {isOpen && <div className="property-type-dropdown">
          <button onClick={() => onSelect('all')} onKeyDown={e => handleDropdownOptionKeyDown(e, onToggle)} className={`property-type-option ${value === 'all' ? 'selected' : ''}`} type="button">
            {allLabel}
          </button>
          {options.map(option => <button key={option.value} onClick={() => onSelect(option.value)} onKeyDown={e => handleDropdownOptionKeyDown(e, onToggle)} className={`property-type-option ${value === option.value ? 'selected' : ''}`} type="button">
              {option.label}
            </button>)}
        </div>}
    </div>;
  const SearchSection = () => <>
      <div className="property-definitions-search-row">
        <div className="property-definitions-search">
          <label htmlFor="property-search" className="sr-only">
            {placeholder}
          </label>
          <input id="property-search" type="text" placeholder={placeholder} value={searchTerm} onChange={e => setSearchTerm(e.target.value)} maxLength={75} className="property-definitions-input" aria-label={placeholder} />
          <span className="property-definitions-input-icon" aria-hidden="true">
            <Icon icon="magnifying-glass" size="16" />
          </span>
        </div>

        <div className="property-definitions-results-count" role="status" aria-live="polite">
          {filteredProperties.length} {filteredProperties.length === 1 ? 'property' : 'properties'}
        </div>
      </div>

      <div className="property-definitions-filter-row">
        <FilterDropdown containerClassName="property-type-filter" value={selectedType} isOpen={typeDropdownOpen} onToggle={() => {
    setFieldTypeDropdownOpen(false);
    setTypeDropdownOpen(prev => !prev);
  }} onSelect={v => {
    setSelectedType(v);
    setTypeDropdownOpen(false);
  }} allLabel="All data types" options={availableTypes.map(type => ({
    value: type,
    label: formatDataType(type)
  }))} formatLabel={formatDataType} />

        <FilterDropdown containerClassName="property-field-type-filter" value={selectedFieldType} isOpen={fieldTypeDropdownOpen} onToggle={() => {
    setTypeDropdownOpen(false);
    setFieldTypeDropdownOpen(prev => !prev);
  }} onSelect={v => {
    setSelectedFieldType(v);
    setFieldTypeDropdownOpen(false);
  }} allLabel="All display types" options={availableFieldTypes.map(ft => ({
    value: ft,
    label: ft
  }))} />

        <button onClick={toggleAllProperties} className="collapse-all-button" type="button" aria-label={allExpanded ? 'Collapse all properties' : 'Expand all properties'}>
          {allExpanded ? 'Collapse all' : 'Expand all'}
        </button>
      </div>
    </>;
  const OptionsList = ({options}) => {
    const list = <ul className="property-options-list">
        {options.map((option, idx) => <li key={idx}>
            {option.label} (<code>{option.value}</code>)
          </li>)}
      </ul>;
    return options.length > 10 ? <Expandable title={`${options.length} options`}>{list}</Expandable> : list;
  };
  const PropertyRow = ({property, isOpen, fieldTypeConfig, hoveredProperty, selectedProperty, copiedLinks, visibleJson, copyAnchorLink, toggleProperty, setHoveredProperty, setVisibleJson, objectPluralName}) => <>
      <dt id={property.name} className="property-definition-term" onMouseEnter={() => setHoveredProperty(property.name)} onMouseLeave={() => setHoveredProperty(null)}>
        <div className={`property-link-icon ${selectedProperty === property.name || hoveredProperty === property.name ? 'selected' : ''}`} onClick={e => {
    e.stopPropagation();
    copyAnchorLink(property.name);
  }} role="button" tabIndex={0} aria-label={`Copy link to ${property.name} property`} onKeyDown={e => {
    if (e.key === 'Enter' || e.key === ' ') {
      e.preventDefault();
      e.stopPropagation();
      copyAnchorLink(property.name);
    }
  }}>
          {copiedLinks[property.name] ? <svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" className="copy-success-icon">
              <path d="M11.6666 3.5L5.24992 9.91667L2.33325 7" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
            </svg> : <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" focusable="false" data-icon-name="Link" class="StyledIcon-sc-186h16e-0 ijKTrl"><path d="M10.47 29.5c-1.95 0-3.9-.74-5.38-2.22s-2.23-3.35-2.23-5.38.79-3.94 2.23-5.38l2.29-2.29c.45-.45 1.17-.45 1.62 0s.45 1.17 0 1.62l-2.29 2.29c-1.01 1.01-1.56 2.34-1.56 3.76s.55 2.76 1.56 3.76a5.34 5.34 0 0 0 7.53 0l2.29-2.29c.45-.45 1.17-.45 1.62 0s.45 1.17 0 1.62l-2.29 2.29a7.59 7.59 0 0 1-5.38 2.22ZM24.18 18.47c-.29 0-.58-.11-.81-.33a1.14 1.14 0 0 1 0-1.62l2.29-2.29a5.34 5.34 0 0 0 0-7.53c-2.08-2.08-5.45-2.07-7.53 0l-2.29 2.29c-.45.45-1.17.45-1.62 0s-.45-1.17 0-1.62l2.29-2.29a7.61 7.61 0 0 1 10.76 0 7.61 7.61 0 0 1 0 10.76l-2.29 2.29c-.22.22-.52.33-.81.33Z"></path><path d="M12.75 20.75c-.29 0-.58-.11-.81-.33a1.14 1.14 0 0 1 0-1.62l6.86-6.86c.45-.45 1.17-.45 1.62 0s.45 1.17 0 1.62l-6.86 6.86c-.22.22-.52.33-.81.33"></path></svg>}
        </div>
        <div className={`property-chevron ${isOpen ? 'open' : ''}`} onClick={() => toggleProperty(property.name)} role="button" tabIndex={0} aria-label={`${isOpen ? 'Collapse' : 'Expand'} ${property.name} property`} onKeyDown={e => {
    if (e.key === 'Enter' || e.key === ' ') {
      e.preventDefault();
      toggleProperty(property.name);
    }
  }}>
          <svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
            <path fillRule="evenodd" clipRule="evenodd" d="M3.38065 0.381075C3.46191 0.299739 3.55841 0.235216 3.66462 0.191193C3.77083 0.147171 3.88468 0.124512 3.99965 0.124512C4.11463 0.124512 4.22847 0.147171 4.33468 0.191193C4.4409 0.235216 4.53739 0.299739 4.61865 0.381075L9.61865 5.38107C9.69999 5.46234 9.76451 5.55883 9.80853 5.66504C9.85256 5.77125 9.87522 5.8851 9.87522 6.00007C9.87522 6.11505 9.85256 6.2289 9.80853 6.33511C9.76451 6.44132 9.69999 6.53781 9.61865 6.61907L4.61865 11.6191C4.45435 11.7834 4.23151 11.8757 3.99915 11.8757C3.76679 11.8757 3.54395 11.7834 3.37965 11.6191C3.21535 11.4548 3.12305 11.2319 3.12305 10.9996C3.12305 10.7672 3.21535 10.5444 3.37965 10.3801L7.76265 6.00007L3.37965 1.61907C3.29832 1.53781 3.23379 1.44132 3.18977 1.33511C3.14575 1.2289 3.12309 1.11505 3.12309 1.00007C3.12309 0.885101 3.14575 0.771255 3.18977 0.665043C3.23379 0.558831 3.29932 0.462337 3.38065 0.381075Z" fill="currentColor" />
          </svg>
        </div>
        <div className="property-definition-content">
          <button onClick={() => toggleProperty(property.name)} aria-expanded={isOpen} type="button" className="property-label-button" aria-label={`${isOpen ? 'Collapse' : 'Expand'} ${property.label}`}>
            <span className="property-label">{property.label}</span>
          </button>
          <CopyCode><code>{property.name}</code></CopyCode>

          {property.json && isOpen && <button onClick={e => {
    e.stopPropagation();
    setVisibleJson(prev => ({
      ...prev,
      [property.name]: !prev[property.name]
    }));
  }} className={`view-json-button ${selectedProperty === property.name || hoveredProperty === property.name ? 'selected' : ''}`} type="button" aria-expanded={visibleJson[property.name] || false} style={{
    marginLeft: 'auto'
  }}>
              <Icon icon="code" size="14" iconType="regular" aria-hidden="true" /> {visibleJson[property.name] ? 'Hide JSON' : 'Show JSON'}
            </button>}
        </div>
      </dt>
      {isOpen && <dd className="property-definition-description" onMouseEnter={() => setHoveredProperty(property.name)} onMouseLeave={() => setHoveredProperty(null)}>
          <div className="property-definition-row">
            <span className="property-data-type" style={{
    backgroundColor: 'unset'
  }}><strong>Data type: </strong> {formatDataType(property.type)}</span>
            <span className="property-field-type">
              <strong>Display type: </strong> <span className={`field-type-icon field-type-icon--${property.fieldType}`} aria-hidden="true" />
              <span>{fieldTypeConfig.label}</span>
            </span>
          </div>

          <div className="property-definition-row property-description-text">
            {property.description}
          </div>

          {property.options && property.options.length > 0 && <div className="property-definition-row">
              <OptionsList options={property.options} />
            </div>}

          {(property.required || property.searchable || property.primaryDisplayProperty || property.secondaryDisplayProperty) && <div className="property-definition-row property-attributes">
              {property.required && <span className="property-attribute">
                  <span className="prop-icon prop-icon--required" aria-hidden="true" />
                  <Tooltip tip={`This property is required for creating ${objectPluralName.toLowerCase()}.`}>Required</Tooltip>
                </span>}
              {property.searchable && <span className="property-attribute">
                  <span className="prop-icon prop-icon--search" aria-hidden="true" />
                  <Tooltip tip={`This property can be used to search for ${objectPluralName.toLowerCase()}.`} cta="Learn more about CRM search" href="/api-reference/latest/crm/search-the-crm">Searchable</Tooltip>
                </span>}
              {property.primaryDisplayProperty && <span className="property-attribute">
                  <span className="prop-icon prop-icon--display-property" aria-hidden="true" />
                  <Tooltip tip={`The main display label in the UI for ${objectPluralName.toLowerCase()}.`}>Primary display property</Tooltip>
                </span>}
              {property.secondaryDisplayProperty && <span className="property-attribute">
                  <span className="prop-icon prop-icon--display-property" aria-hidden="true" />
                  <Tooltip tip={`A secondary label in the UI for ${objectPluralName.toLowerCase()}.`}>Secondary display property</Tooltip>
                </span>}
            </div>}

          {property.json && visibleJson[property.name] && <div className="property-json-viewer" style={{
    marginTop: '1rem'
  }}>
              <CodeBlock language="json">
              {JSON.stringify(property.json, null, 2)}
              </CodeBlock>
            </div>}
        </dd>}
    </>;
  const [mounted, setMounted] = useState(false);
  const [searchTerm, setSearchTerm] = useState('');
  const [debouncedSearchTerm, setDebouncedSearchTerm] = useState('');
  const [openStates, setOpenStates] = useState({});
  const [showBackToTop, setShowBackToTop] = useState(false);
  const [selectedType, setSelectedType] = useState('all');
  const [selectedFieldType, setSelectedFieldType] = useState('all');
  const [typeDropdownOpen, setTypeDropdownOpen] = useState(false);
  const [fieldTypeDropdownOpen, setFieldTypeDropdownOpen] = useState(false);
  const [allExpanded, setAllExpanded] = useState(true);
  const [selectedProperty, setSelectedProperty] = useState(null);
  const [hoveredProperty, setHoveredProperty] = useState(null);
  const [visibleJson, setVisibleJson] = useState({});
  const [copiedLinks, setCopiedLinks] = useState({});
  const containerRef = useRef(null);
  const listRef = useRef(null);
  useEffect(() => setMounted(true), []);
  useEffect(() => {
    if (!mounted || !window.location.hash) return;
    const targetId = window.location.hash.substring(1);
    setTimeout(() => {
      const targetElement = document.getElementById(targetId);
      if (targetElement) {
        targetElement.scrollIntoView({
          behavior: 'smooth',
          block: 'start'
        });
        setSelectedProperty(targetId);
      }
    }, 100);
  }, [mounted]);
  useEffect(() => {
    if (!mounted) return;
    const timer = setTimeout(() => {
      setDebouncedSearchTerm(searchTerm);
    }, 300);
    return () => clearTimeout(timer);
  }, [searchTerm, mounted]);
  useEffect(() => {
    if (!mounted) return;
    const handleScroll = () => {
      if (listRef.current) {
        const listTop = listRef.current.getBoundingClientRect().top;
        setShowBackToTop(listTop < 0);
      }
    };
    window.addEventListener('scroll', handleScroll);
    handleScroll();
    return () => window.removeEventListener('scroll', handleScroll);
  }, [mounted]);
  useEffect(() => {
    if (!mounted) return;
    const handleClickOutside = event => {
      if (typeDropdownOpen && !event.target.closest('.property-type-filter')) {
        setTypeDropdownOpen(false);
      }
      if (fieldTypeDropdownOpen && !event.target.closest('.property-field-type-filter')) {
        setFieldTypeDropdownOpen(false);
      }
    };
    document.addEventListener('click', handleClickOutside);
    return () => document.removeEventListener('click', handleClickOutside);
  }, [typeDropdownOpen, fieldTypeDropdownOpen, mounted]);
  const properties = Array.isArray(children) ? children : [children];
  const propertyData = useMemo(() => properties.filter(child => child && child.type === Property).map(child => child.props), [children]);
  const availableTypes = useMemo(() => [...new Set(propertyData.filter(p => selectedFieldType === 'all' || fieldTypeConfigs[p.fieldType]?.label === selectedFieldType).map(p => p.type).filter(Boolean))].sort(), [propertyData, selectedFieldType]);
  const availableFieldTypes = useMemo(() => [...new Set(propertyData.filter(p => selectedType === 'all' || p.type === selectedType).map(p => fieldTypeConfigs[p.fieldType]?.label).filter(Boolean))].sort(), [propertyData, selectedType]);
  useEffect(() => {
    if (!mounted || openStates && Object.keys(openStates).length > 0) return;
    const initialStates = {};
    propertyData.forEach(prop => {
      initialStates[prop.name] = prop.expanded !== false;
    });
    setOpenStates(initialStates);
  }, [propertyData, mounted]);
  const filteredProperties = useMemo(() => {
    if (!mounted) return [];
    return propertyData.filter(prop => {
      const matchesSearch = !debouncedSearchTerm || (prop.name && prop.name.toLowerCase().includes(debouncedSearchTerm.toLowerCase()) || prop.label && prop.label.toLowerCase().includes(debouncedSearchTerm.toLowerCase()) || prop.description && prop.description.toLowerCase().includes(debouncedSearchTerm.toLowerCase()));
      const matchesType = selectedType === 'all' || prop.type === selectedType;
      const matchesFieldType = selectedFieldType === 'all' || prop.fieldType && fieldTypeConfigs[prop.fieldType] && fieldTypeConfigs[prop.fieldType].label === selectedFieldType;
      return matchesSearch && matchesType && matchesFieldType;
    });
  }, [propertyData, debouncedSearchTerm, selectedType, selectedFieldType, mounted]);
  const toggleProperty = useCallback(name => {
    setOpenStates(prev => ({
      ...prev,
      [name]: !prev[name]
    }));
  }, []);
  const toggleAllProperties = useCallback(() => {
    const newExpandedState = !allExpanded;
    setAllExpanded(newExpandedState);
    const newOpenStates = {};
    propertyData.forEach(prop => {
      newOpenStates[prop.name] = newExpandedState;
    });
    setOpenStates(newOpenStates);
  }, [allExpanded, propertyData]);
  const copyAnchorLink = useCallback(async propertyName => {
    const url = `${window.location.origin}${window.location.pathname}#${propertyName}`;
    setSelectedProperty(propertyName);
    try {
      await navigator.clipboard.writeText(url);
      setCopiedLinks(prev => ({
        ...prev,
        [propertyName]: true
      }));
      const targetElement = document.getElementById(propertyName);
      if (targetElement) {
        if (compact) {
          const container = listRef.current;
          if (container) {
            const containerRect = container.getBoundingClientRect();
            const targetRect = targetElement.getBoundingClientRect();
            const scrollOffset = targetRect.top - containerRect.top + container.scrollTop - 20;
            container.scrollTo({
              top: scrollOffset,
              behavior: 'smooth'
            });
          }
        } else {
          targetElement.scrollIntoView({
            behavior: 'smooth',
            block: 'start'
          });
        }
        setTimeout(() => {
          targetElement.focus({
            preventScroll: true
          });
        }, 500);
      }
      history.replaceState(null, null, `#${propertyName}`);
      setTimeout(() => {
        setCopiedLinks(prev => ({
          ...prev,
          [propertyName]: false
        }));
      }, 1500);
    } catch (err) {
      console.error('Failed to copy link: ', err);
    }
  }, [compact]);
  const scrollToTop = useCallback(() => {
    if (containerRef.current) {
      containerRef.current.scrollIntoView({
        behavior: 'smooth',
        block: 'start'
      });
    }
  }, []);
  if (!mounted) {
    return <div id="property-definitions" className="property-definitions-wrapper skeleton-loader-wrapper" ref={containerRef} role="region" aria-label="Loading properties" aria-busy="true">
        {searchable && <>
            <div className="property-definitions-search-row skeleton-search-row">
              <div className="skeleton-search-input"></div>
            </div>
            <div className="property-definitions-filter-row skeleton-filter-row">
              <div className="skeleton-filter-button"></div>
              <div className="skeleton-filter-button"></div>
              <div className="skeleton-filter-button"></div>
            </div>
          </>}
        <div className="skeleton-items-container">
          {[1, 2, 3, 4, 5].map(i => <div key={i} className="skeleton-property-item">
              <div className="skeleton-property-placeholder"></div>
            </div>)}
        </div>
      </div>;
  }
  return <div id="property-definitions" className="property-definitions-wrapper" ref={containerRef}>
      {searchable && SearchSection()}

      <dl className="property-definitions-list" ref={listRef} style={compact ? {
    maxHeight: '800px',
    overflowY: 'scroll',
    minHeight: '200px'
  } : {}}>
        {filteredProperties.length > 0 ? filteredProperties.map(property => <div key={property.name} className="property-row">
              {PropertyRow({
    property,
    isOpen: openStates[property.name] !== undefined ? openStates[property.name] : true,
    fieldTypeConfig: fieldTypeConfigs[property.fieldType] || ({
      label: property.fieldType
    }),
    hoveredProperty,
    selectedProperty,
    copiedLinks,
    visibleJson,
    copyAnchorLink,
    toggleProperty,
    setHoveredProperty,
    setVisibleJson,
    objectPluralName
  })}
            </div>) : <div className="property-definitions-empty">
            {!debouncedSearchTerm.trim() && (selectedType !== 'all' || selectedFieldType !== 'all') ? 'No properties found matching the selected filters.' : `No properties found matching "${searchTerm}"`}
          </div>}
      </dl>
    </div>;
};

export const PostmanCard = ({title, collectionId}) => {
  return <div className="card-condensed-cta">
      <Card title={title ? title : "Postman collection"} href={`https://app.getpostman.com/run-collection/${collectionId}`} horizontal={true} cta="Run in Postman" icon={<svg xmlns="http://www.w3.org/2000/svg" width={25} height={25} preserveAspectRatio="xMidYMid" viewBox="0 0 256 256">
              <path fill="#FF6C37" d="M254.953 144.253c8.959-70.131-40.569-134.248-110.572-143.206C74.378-7.912 10.005 41.616 1.047 111.619c-8.959 70.003 40.569 134.248 110.572 143.334 70.131 8.959 134.248-40.569 143.334-110.7Z" />
              <path fill="#FFF" d="m174.2 82.184-54.007 54.007-15.229-15.23c53.11-53.11 58.358-48.503 69.236-38.777Z" />
              <path fill="#FF6C37" d="M120.193 137.47c-.384 0-.64-.128-.895-.384l-15.358-15.229a1.237 1.237 0 0 1 0-1.792c54.007-54.006 59.638-48.887 71.028-38.649.255.256.383.512.383.896s-.128.64-.383.896l-54.007 53.878c-.128.256-.512.384-.768.384Zm-13.437-16.509 13.437 13.438 52.087-52.087c-9.47-8.446-15.87-11.006-65.524 38.65Z" />
              <path fill="#FFF" d="m135.679 151.676-14.718-14.718 54.007-54.006c14.46 14.59-7.167 38.265-39.29 68.724Z" />
              <path fill="#FF6C37" d="M135.679 152.956c-.384 0-.64-.128-.896-.384l-14.718-14.718c-.256-.256-.256-.512-.256-.896s.128-.64.384-.895L174.2 82.056a1.237 1.237 0 0 1 1.791 0 15.58 15.58 0 0 1 4.991 11.902c-.256 14.206-16.38 32.25-44.28 58.614-.383.256-.767.384-1.023.384Zm-12.926-15.998c8.19 8.319 11.646 11.646 12.926 12.926 21.5-20.476 42.36-41.464 42.488-55.926.128-3.327-1.152-6.655-3.327-9.214l-52.087 52.214Z" />
              <path fill="#FFF" d="m105.22 121.345 10.878 10.878c.256.256.256.512 0 .768-.128.128-.128.128-.256.128l-22.524 4.863c-1.152.128-2.175-.64-2.431-1.791-.128-.64.128-1.28.512-1.664l13.053-13.054c.256-.256.64-.384.768-.128Z" />
              <path fill="#FF6C37" d="M92.934 139.262c-1.92 0-3.327-1.536-3.327-3.455 0-.896.384-1.792 1.024-2.432l13.053-13.054c.768-.64 1.792-.64 2.56 0l10.878 10.878c.768.64.768 1.792 0 2.56-.256.256-.512.384-.896.512l-22.524 4.863c-.256 0-.512.128-.768.128Zm11.902-16.51-12.542 12.543c-.256.256-.383.64-.128 1.024.128.383.512.511.896.383l21.116-4.607-9.342-9.342Z" />
              <path fill="#FFF" d="M202.739 52.238c-8.191-7.935-21.373-7.679-29.307.64-7.935 8.318-7.679 21.372.64 29.306A20.678 20.678 0 0 0 199.155 85l-14.59-14.59 18.174-18.172Z" />
              <path fill="#FF6C37" d="M188.405 89.223c-12.158 0-22.012-9.854-22.012-22.012 0-12.158 9.854-22.012 22.012-22.012 5.631 0 11.134 2.176 15.23 6.143.255.256.383.512.383.896s-.128.64-.384.895L186.357 70.41l13.566 13.566c.512.512.512 1.28 0 1.792l-.256.256c-3.327 2.047-7.295 3.199-11.262 3.199Zm0-41.337c-10.75 0-19.452 8.703-19.324 19.453 0 10.75 8.702 19.452 19.452 19.324 2.944 0 5.887-.64 8.575-2.047l-13.438-13.31c-.256-.256-.384-.512-.384-.896s.128-.64.384-.895l17.149-17.15c-3.456-2.943-7.807-4.479-12.414-4.479Z" />
              <path fill="#FFF" d="m203.122 52.622-.255-.256-18.301 18.044 14.461 14.462c1.408-.896 2.816-1.92 3.967-3.072a20.51 20.51 0 0 0 .128-29.178Z" />
              <path fill="#FF6C37" d="M199.155 86.28c-.384 0-.64-.128-.896-.384l-14.589-14.59c-.256-.256-.384-.512-.384-.896s.128-.64.384-.895l18.173-18.173a1.237 1.237 0 0 1 1.791 0l.384.256c8.575 8.574 8.575 22.396.128 31.098-1.28 1.28-2.687 2.432-4.223 3.328-.384.128-.64.256-.768.256Zm-12.798-15.87 12.926 12.926c1.024-.64 2.048-1.536 2.816-2.304 7.294-7.294 7.678-19.196.64-26.875L186.357 70.41Z" />
              <path fill="#FFF" d="M176.375 84.488a7.879 7.879 0 0 0-11.134 0l-48.247 48.247 8.063 8.063 51.062-44.792c3.328-2.816 3.584-7.807.768-11.134-.256-.128-.384-.256-.512-.384Z" />
              <path fill="#FF6C37" d="M124.929 142.077c-.384 0-.64-.128-.896-.383l-8.063-8.063a1.237 1.237 0 0 1 0-1.792l48.247-48.247a9.115 9.115 0 0 1 12.926 0 9.115 9.115 0 0 1 0 12.926l-.384.384-51.063 44.792c-.128.255-.384.383-.767.383Zm-6.143-9.342 6.27 6.271 50.167-44.024c2.816-2.304 3.072-6.527.768-9.342-2.303-2.816-6.526-3.072-9.342-.768-.128.128-.256.256-.512.384l-47.351 47.48Z" />
              <path fill="#FFF" d="M80.009 187.637c-.512.256-.768.768-.64 1.28l2.175 9.214c.512 1.28-.256 2.816-1.663 3.2-1.024.384-2.176 0-2.816-.768l-14.077-13.95 45.943-45.943 15.87.256 10.75 10.75c-2.56 2.175-18.045 17.149-55.542 35.961Z" />
              <path fill="#FF6C37" d="M78.985 202.61c-1.024 0-2.048-.383-2.688-1.151l-13.95-13.95c-.255-.256-.383-.512-.383-.896 0-.383.128-.64.384-.895l45.944-45.944c.256-.256.64-.384.895-.384l15.87.256c.383 0 .64.128.895.384l10.75 10.75c.256.256.384.64.384 1.024s-.128.64-.512.896l-.895.767c-13.566 11.902-31.995 23.804-54.902 35.194l2.175 9.086c.384 1.664-.384 3.456-1.92 4.352-.767.384-1.407.512-2.047.512Zm-14.078-15.997 13.182 13.054c.384.64 1.152.896 1.792.512.64-.384.896-1.152.512-1.792l-2.176-9.214c-.256-1.152.256-2.176 1.28-2.688 22.652-11.39 40.952-23.163 54.39-34.81l-9.47-9.47-14.718-.256-44.792 44.664Z" />
              <path fill="#FFF" d="m52.11 197.62 11.006-11.007 16.38 16.381-26.107-1.791c-1.151-.128-1.92-1.152-1.791-2.304 0-.512.128-1.024.512-1.28Z" />
              <path fill="#FF6C37" d="m79.497 204.146-26.236-1.791c-1.92-.128-3.199-1.792-3.071-3.712.128-.768.384-1.535 1.024-2.047L62.22 185.59a1.237 1.237 0 0 1 1.792 0l16.38 16.38c.385.385.512.897.257 1.408-.256.512-.64.768-1.152.768Zm-16.381-15.74-10.11 10.11c-.384.255-.384.895 0 1.151.127.128.255.256.511.256l22.652 1.536-13.053-13.054ZM104.452 146.557c-.768 0-1.28-.64-1.28-1.28 0-.384.128-.64.384-.896l12.414-12.414a1.237 1.237 0 0 1 1.792 0l8.062 8.063c.384.384.512.768.384 1.28-.128.384-.512.767-1.023.895l-20.477 4.352h-.256Zm12.414-11.902-8.446 8.446 13.821-2.943-5.375-5.503Z" />
              <path fill="#FFF" d="m124.8 140.926-14.077 3.071c-1.024.256-2.048-.384-2.303-1.408-.128-.64 0-1.28.511-1.791l7.807-7.807 8.063 7.935Z" />
              <path fill="#FF6C37" d="M110.467 145.277a3.168 3.168 0 0 1-3.2-3.2c0-.895.385-1.663.897-2.303l7.806-7.807a1.237 1.237 0 0 1 1.792 0l8.062 8.063c.384.384.512.768.384 1.28-.128.384-.512.767-1.023.895l-14.078 3.072h-.64Zm6.399-10.622-6.91 6.91c-.257.257-.257.512-.129.768s.384.384.768.384l11.774-2.56-5.503-5.502ZM203.25 64.907c-.256-.767-1.151-1.151-1.92-.895-.767.255-1.151 1.151-.895 1.92 0 .127.128.255.128.383.768 1.536.512 3.455-.512 4.863-.512.64-.384 1.536.128 2.048.64.512 1.536.384 2.048-.256 1.92-2.432 2.303-5.503 1.023-8.063Z" />
            </svg>} />
    </div>;
};

export const ScopesList = ({scopes = [], description = "This API requires one of the following scopes:"}) => {
  if (!scopes || scopes.length === 0) {
    return null;
  }
  const sortedScopes = scopes.sort((a, b) => a.localeCompare(b));
  return <div>
      <div className="text-sm mb-2">{description}</div>
      <div>
        {sortedScopes.map((scope, index) => <div key={index}>
            <code>
              <span className="text-xs">{scope}</span>
            </code>
          </div>)}
      </div>
    </div>;
};

<PostmanCard collectionId="26126890-3b40e54a-2cb6-4107-82fa-1c4be3feb68a" />

<Accordion title="Scope requirements">
  <ScopesList
    scopes={[
  'crm.objects.goals.read',
  'crm.objects.goals.write'
]}
  />
</Accordion>

In HubSpot, goals are used to create user-specific quotas for their sales and services teams based on templates provided by HubSpot. The goals API allow you to retrieve goals data in your HubSpot account.

Learn more about [using goals in HubSpot](https://knowledge.hubspot.com/reports/create-sales-goals).

## Understanding Goal Architecture

Unlike standard objects (like Deals or Contacts) which exist as single rows, a "Goal" in HubSpot is a container for multiple time-bound objects. To successfully create or manage goals, you must understand the hierarchy of the three key components: **Goal Family**, **Goal Target Group**, and **Goal Target**.

### The Goal Hierarchy

The API defines a goal using a nesting structure linked by specific IDs.

#### Goal Family (The "Goal")

This is what a user perceives as "One Goal" (e.g., "2025 Revenue Quota"). It is identified by the `hs_group_correlation_uuid`. This ID links every time-slice together into one cohesive unit.

<Frame>
  <img src="https://www.hubspot.com/hubfs/Knowledge_Base_2023-24-25/KB-Goals/KB-Goals%20API/goals-group-correlation-ID.png" alt="A screenshot of the Edit targets tab for the Calls made goal in HubSpot. The view is set to Users with goals for the year 2026. A table lists two representatives, Daniel the Cat and Jess Geist, both with a Number of calls unit of measurement. Each rep has a target of 100 for the months of February, March, April, and May 2026. The All reps row at the bottom shows a total of 200 calls for each of these four months. The table also includes an Actions column with Apply target links and an Import user targets button above the table." />
</Frame>

In your account, all targets (whether weekly, monthly, quarterly, or yearly) appear under a single goal name (e.g., Calls made) because they share the same `hs_group_correlation_uuid`. If this ID differs across targets, they will appear as separate goals.

#### Goal Target Group (The Schedule)

This represents the schedule or assignment constraints (e.g., "Monthly targets for User A"). It is identified by the `hs_goal_target_group_id`. All time periods for that specific user's schedule share this ID.

<Frame>
  <img src="https://www.hubspot.com/hubfs/Knowledge_Base_2023-24-25/KB-Goals/KB-Goals%20API/goals-goal-target-group-ID.png" alt="A screenshot of the Edit targets tab for the Calls made goal in HubSpot. There are red outlines around the rows for Daniel the Cat and Jess Geist. The outlines highlight these two rows, which contain the target information for the two representatives for the months of February, March, April, and May 2026. The Apply target links, the numerical target values, and the unit of measurement are all included within the outlined areas." />
</Frame>

In your account, this determines which targets are grouped together for a specific assignment. For user goals, the `hubspot_owner_id` property determines who sees this goal in their dashboard. For team goals, the `hs_assignee_team_id` (or `hubspot_team_id`) property is used instead to assign the goal to the entire team.

#### Goal Target (The Time Slice)

These are the individual objects holding the data. For a monthly goal, there are 12 separate `goal_target` objects (Jan, Feb, Mar...). Each has its own `hs_start_datetime` and `hs_target_amount`.

<Frame>
  <img src="https://www.hubspot.com/hubfs/Knowledge_Base_2023-24-25/KB-Goals/KB-Goals%20API/goals-goal-target.png" alt="This image displays the Edit targets interface for the Calls made goal. Red outlines highlight the individual target input cells for February, March, April, and May 2026. Each outlined cell contains a value of 100 for representatives Daniel the Cat and Jess Geist, emphasizing the specific goal targets for each time slice." />
</Frame>

In your account, each target appears as a distinct column in the goal timeline, showing the specific target for that period and tracking progress against that individual slice.

### Example: Structure of a Monthly Goal

The JSON below illustrates two separate goal objects: one for January and one for February.

While the target data (dates and amounts) changes for each month, they belong to the same **Goal Family** and **Goal Target Group**. As shown in the highlighted lines, the `hs_goal_name`, `hs_group_correlation_uuid`, and `hs_goal_target_group_id` remain constant to link these objects into a single cohesive goal schedule.

```json highlight={4-6, 15-17} theme={null}
[
  {
    "properties": {
      "hs_goal_name": "2025 Revenue Quota",
      "hs_group_correlation_uuid": "40499cb1-d8e7-495d-a1c7-07e3ed4b5468",
      "hs_goal_target_group_id": "1234567",
      "hubspot_owner_id": "901831746",
      "hs_start_datetime": "2025-01-01T00:00:00Z",
      "hs_end_datetime": "2025-01-31T23:59:59.999Z",
      "hs_target_amount": "5000.00"
    }
  },
  {
    "properties": {
      "hs_goal_name": "2025 Revenue Quota",
      "hs_group_correlation_uuid": "40499cb1-d8e7-495d-a1c7-07e3ed4b5468",
      "hs_goal_target_group_id": "1234567",
      "hubspot_owner_id": "901831746",
      "hs_start_datetime": "2025-02-01T00:00:00Z",
      "hs_end_datetime": "2025-02-28T23:59:59.999Z",
      "hs_target_amount": "6000.00"
    }
  }
]
```

## Retrieve goals

To retrieve goals, make a request in one of the following ways:

* **Retrieve a single target:** `GET /crm/v3/objects/goal_targets/{goalTargetId}/`
* **Retrieve all targets:** `GET /crm/v3/objects/goal_targets`
* **Search for targets:** `POST /crm/v3/objects/goal_targets/search`

To retrieve goals that meet a specific set of criteria (filtering), you can make a `POST` request to the search endpoint and include filters in the request body. Learn more about [searching the CRM](/api-reference/legacy/crm/search-the-crm).

For example, to retrieve a goal with an ID of `44027423340`, the request URL would be the following:

`https://api.hubapi.com/crm/v3/objects/goal_targets/44027423340/`

The response will include a few default properties, including the create date, last modified date.

```json theme={null}
{
  "id": "87504620389",
  "properties": {
    "hs_createdate": "2021-11-30T22:18:49.923Z",
    "hs_lastmodifieddate": "2023-12-11T19:21:32.851Z",
    "hs_object_id": "87504620389"
  },
  "createdAt": "2021-11-30T22:18:49.923Z",
  "updatedAt": "2023-12-11T19:21:32.851Z",
  "archived": false
}
```

To return specific properties, include a `properties` query parameter in the request URL along with comma-separated property names. Learn more about [goal properties below](#goal-properties).

For example, making a `GET` request to the following URL would result in the response below:

`crm/v3/objects/goal_targets/{goalTargetId}?properties=hs_goal_name,hs_target_amount`

```json theme={null}
{
  "id": "87504620389",
  "properties": {
    "hs_createdate": "2021-11-30T22:18:49.923Z",
    "hs_lastmodifieddate": "2023-12-11T19:21:32.851Z",
    "hs_object_id": "87504620389"
  },
  "createdAt": "2021-11-30T22:18:49.923Z",
  "updatedAt": "2023-12-11T19:21:32.851Z",
  "archived": false
}
```

## Create goals

To create goals, make a `POST` request to `/crm/v3/objects/goal_targets/batch/create`.

To ensure these objects appear as a single goal in the UI, your batch request must adhere to specific architectural constraints:

* **Shared Identifiers:** Every target object in the batch must share the same `hs_group_correlation_uuid` and `hs_goal_target_group_id`. This links them into a "Goal Family".
* **Sequential Dates:** You must increment the `hs_start_datetime` and `hs_end_datetime` for each object. For monthly goals, start dates must be the first millisecond of the month, and end dates must be the last millisecond of the month.
* **Milestone Accuracy:** The number of objects must match the `hs_milestone` frequency (e.g., creating 12 objects for a "monthly" milestone).

This example shows the creation of the first two months of an annual sales quota goal. Note that the UUIDs remain constant while the dates increment.

`/crm/v3/objects/goal_targets/batch/create`

```json theme={null}
{
  "inputs": [
    {
      "properties": {
        "hs_goal_name": "Sales Quota 2027",
        "hs_milestone": "monthly",
        "hs_goal_type": "sales_quota",
        "hs_target_amount": "1200.00",
        "hs_start_datetime": "2027-01-01T00:00:00Z",
        "hs_end_datetime": "2027-01-31T23:59:59.999Z",
        "hs_group_correlation_uuid": "40499cb1-d8e7-495d-a1c7-07e3ed4b5468",
        "hs_goal_target_group_id": "1234567"
      }
    },
    {
      "properties": {
        "hs_goal_name": "Sales Quota 2027",
        "hs_milestone": "monthly",
        "hs_goal_type": "sales_quota",
        "hs_target_amount": "1200.00",
        "hs_start_datetime": "2027-02-01T00:00:00Z",
        "hs_end_datetime": "2027-02-28T23:59:59.999Z",
        "hs_group_correlation_uuid": "40499cb1-d8e7-495d-a1c7-07e3ed4b5468",
        "hs_goal_target_group_id": "1234567"
      }
    }
  ]
}
```

## Update Goals

To update goals, make a request in one of the following ways:

* **Update a single target:** `PATCH /crm/v3/objects/goal_targets/{goalTargetId}`
* **Batch update multiple targets:** `POST /crm/v3/objects/goal_targets/batch/update`

Because a "Goal" consists of multiple independent objects (e.g., 12 monthly targets), you must choose the correct update method to avoid breaking the goal structure in the UI.

* **When to use Single Update (`PATCH`):** Use this when changing data specific to one time slice.
  * **Example:** Changing the `hs_target_amount` for just the month of October.
  * **Example:** Manually overriding the `hs_kpi_value` for a specific month.
* **When to use Batch Update (`POST`):** Use this when changing properties that define the **Goal Family**. If you change these on one object but not the others, the goal may disappear from the UI or appear as duplicates.
  * **Example:** Renaming the goal (`hs_goal_name`). You must update all 12 targets.
  * **Example:** Changing the pipeline (`hs_pipeline_ids`). You must update all 12 targets.

This example shows updates to the target amount for a specific month and triggers a notification to the user.

`PATCH /crm/v3/objects/goal_targets/{goalTargetId}`

```json theme={null}
{
  "properties": {
    "hs_target_amount": "5500.00",
    "hs_should_notify_on_edit_updates": "true"
  }
}
```

## Delete Goals

To delete goals, make a request in one of the following ways:

* **Delete a single target:** `DELETE /crm/v3/objects/goal_targets/{goalTargetId}`
* **Batch delete multiple targets:** `POST /crm/v3/objects/goal_targets/batch/archive`

Because a standard goal consists of multiple distinct objects (e.g., 12 monthly targets), you must understand the scope of your deletion request.

* **Deleting a Single Target (`DELETE`):** If you use the `DELETE` endpoint on a single ID, you are removing only that specific slice of time.
  * **Example:** If you delete the target for "January," the goal will still exist in the UI for February through December. The goal family remains active, but the start date or total target amount may calculate incorrectly in reports.
* **Deleting a Goal Family (`POST`):** To completely remove a goal (e.g., "2025 Revenue Quota") from the system, you must delete every target object associated with that goal's `hs_group_correlation_uuid`.
  * **Example:** You must first query the goal targets to retrieve all IDs associated with the Goal Family, and then use the batch archive endpoint to delete them all simultaneously.

This example shows the deletion of an entire quarterly goal. You must include the IDs for all four quarters in the batch archive request.

`POST /crm/v3/objects/goal_targets/batch/archive`

```json theme={null}
{
  "inputs": [
    {"id": "11111"},
    {"id": "22222"},
    {"id": "33333"},
    {"id": "44444"}
  ]
}
```

## Goals properties

When making a `GET` request to the Goals API, you can also request specific goal properties.

For example, if you wanted to include properties such as `hs_goal_name`, `hs_target_amount`, `hs_start_datetime`, `hs_end_datetime`, and `hs_created_by_user_id`, the request URL may resemble the following:

`https://api.hubapi.com/crm/v3/objects/goal_targets/44027423340?properties=hs_goal_name,hs_target_amount,hs_start_datetime,hs_end_datetime,hs_created_by_user_id`

The response may look similar to the JSON excerpt below:

```json theme={null}
{
  "id": "44027423340",
  "properties": {
    "hs_created_by_user_id": "885536",
    "hs_createdate": "2023-02-15T15:53:07.080Z",
    "hs_end_datetime": "2024-01-01T00:00:00Z",
    "hs_goal_name": "Revenue Goal 2023",
    "hs_lastmodifieddate": "2023-02-16T10:02:21.131Z",
    "hs_object_id": "44027423340",
    "hs_start_datetime": "2023-12-01T00:00:00Z",
    "hs_target_amount": "2000.00"
  },
  "createdAt": "2023-02-15T15:53:07.080Z",
  "updatedAt": "2023-02-16T10:02:21.131Z",
  "archived": false
}
```

The available properties and their descriptions can be found in the Goal Property Glossary below.

## Goal Property Glossary

<PropertyDefinitions searchable={true} objectPluralName="goals" compact={false}>
  <Property name="hs_goal_name" label="Goal name" type="string" fieldType="text" description="The name of the goal." primaryDisplayProperty={true} searchable={true} />

  <Property name="hs_start_datetime" label="Start datetime" type="datetime" fieldType="date" description="The first day that goal target's date range covers" secondaryDisplayProperty={true} searchable={true} />

  <Property name="hs_end_datetime" label="End datetime" type="datetime" fieldType="date" description="The last day covered by the Goal Target's date range." />

  <Property
    name="hs_milestone"
    label="Milestone"
    type="enumeration"
    fieldType="select"
    description="The period during which a Goal Target is active"
    options={[
  { label: "Daily", value: "daily" },
  { label: "Weekly", value: "weekly" },
  { label: "Monthly", value: "monthly" },
  { label: "Quarterly", value: "quarterly" },
  { label: "Yearly", value: "yearly" },
  { label: "Custom", value: "custom" }
]}
  />

  <Property name="hs_pipeline_ids" label="Pipeline ids" type="enumeration" fieldType="checkbox" description="List of deal pipelines that the quota applies to. Used to calculate kpi values" />

  <Property name="hs_pipelines" label="Pipelines" type="string" fieldType="text" description="A serialized list of pipeline IDs used to filter the KPI value calculation" />

  <Property name="hs_target_amount" label="Target amount" type="number" fieldType="number" description="The target amount for this goal target" searchable={true} />

  <Property
    name="hs_goal_type"
    label="Goal type"
    type="enumeration"
    fieldType="select"
    description="The goal type"
    options={[
  { label: "Sales Quota", value: "sales_quota" },
  { label: "Deals Created", value: "deals_created" },
  { label: "Ad spend", value: "ad_spend" },
  { label: "Average ticket resolution time", value: "average_ticket_resolution_time" },
  { label: "Average ticket response time", value: "average_ticket_response_time" },
  { label: "Calls made", value: "calls_made" },
  { label: "Meetings booked", value: "meetings_booked" },
  { label: "Tickets closed", value: "tickets_closed" },
  { label: "Contact lifecycle", value: "contact_lifecycle" },
  { label: "Number of network conversions", value: "number_of_network_conversions" },
  { label: "Number of contacts", value: "number_of_contacts" },
  { label: "Contacts first form submission", value: "contacts_first_form_submission" },
  { label: "Standard object custom goal", value: "standard_object_custom_goal" },
  { label: "Cost per contact lifecycle", value: "cost_per_contact_lifecycle" },
  { label: "Contacts last ad interaction", value: "contacts_last_ad_interaction" },
  { label: "Number of marketing campaign influence contacts", value: "marketing_campaign_influence_contacts" },
  { label: "Campaign Revenue", value: "campaign_revenue" },
  { label: "Number of traffic sessions to websites or landing pages or blogposts", value: "website_traffic" },
  { label: "Number of deals with revenue attributed to campaign revenue", value: "campaign_deal_count" },
  { label: "Revenue amount of closed-won deals associated with a campaign", value: "campaign_deal_amount" },
  { label: "Number of contacts in a lifecycle stage attributed to a campaign", value: "campaign_number_of_contact_lifecycle" },
  { label: "Cost per contact in a lifecycle stage attributed to a campaign", value: "campaign_cost_per_contact_lifecycle" },
  { label: "Partner Sourced Deals Created", value: "sourced_deals_created" },
  { label: "Partner Sourced Deals Won", value: "sourced_deals_won" },
  { label: "Partner Sourced Deal Mrr", value: "sourced_deal_mrr" },
  { label: "Partner Assisted Deal Mrr", value: "assisted_deal_mrr" },
  { label: "Leads Created", value: "leads_created" },
  { label: "Emails Sent", value: "emails_sent" },
  { label: "Tasks Completed", value: "tasks_completed" },
  { label: "Notes Created", value: "notes_created" },
  { label: "Conversations Closed", value: "conversations_closed" },
  { label: "Activities Completed", value: "activities_completed" }
]}
  />

  <Property name="hs_kpi_metric_type" label="kpi_metric_type" type="string" fieldType="text" description="Type of metric used to aggregate the property name" />

  <Property name="hs_kpi_time_period_property" label="kpi_time_period_property" type="string" fieldType="text" description="Time period property" />

  <Property
    name="hs_kpi_time_period_property_type"
    label="kpi_time_period_property_type"
    type="enumeration"
    fieldType="checkbox"
    options={[
  { label: "Date", value: "date" },
  { label: "Datetime", value: "datetime" }
]}
  />

  <Property name="hs_kpi_tracking_method" label="kpi_tracking_method" type="string" fieldType="text" description="Tracking method for progress directionality" />

  <Property
    name="hs_kpi_unit_type"
    label="Kpi unit type"
    type="enumeration"
    fieldType="checkbox"
    description="Unit type of the kpi calculation"
    options={[
  { label: "Currency", value: "currency" },
  { label: "Number", value: "number" },
  { label: "Duration", value: "duration" },
  { label: "Decimal", value: "decimal" }
]}
  />

  <Property name="hs_goal_target_currency_code" label="Goal target currency code" type="enumeration" fieldType="select" description="Currency code for the goal target" />

  <Property name="hs_kpi_property_name" label="kpi_property_name" type="string" fieldType="text" description="Name of the property on the object type aggregated as the KPI value." />

  <Property name="hs_kpi_object_type_id" label="Kpi object type id" type="string" fieldType="text" description="The ObjectTypeId of the object the KPI values are based on" />

  <Property name="hs_fiscal_year_offset" label="Fiscal year offset" type="number" fieldType="number" description="Represents the number of months the fiscal year is away from a standard calendar year (0 means the fiscal year starts in January)." />

  <Property name="hs_kpi_value" label="Goal progress amount" type="number" fieldType="number" description="The latest KPI value for this goal target" searchable={true} />

  <Property name="hs_forecast_type_id" label="Forecast type id" type="number" fieldType="number" description="Optional forecast type id used to set the goal" />

  <Property name="hs_assignee_user_id" label="Assignee user ID" type="number" fieldType="number" description="The user ID of the assigned user of the goal (unpopulated if the goal is not user-assigned)" />

  <Property name="hs_assignee_team_id" label="Assignee team ID" type="number" fieldType="number" description="The team ID of the assigned team of the goal (unpopulated if the goal is not team-assigned or team-by-user-assigned)" />

  <Property name="hs_kpi_filter_groups" label="kpi_filter_groups" type="string" fieldType="text" description="Filter groups for KPI calculations" />

  <Property name="hs_group_correlation_uuid" label="Goal ID" type="string" fieldType="text" description="Unique ID set on all Goal Targets and Goal Target Groups created by a single request" />

  <Property name="hs_goal_target_group_id" label="Goal Target Group ID" type="number" fieldType="number" description="Object ID of the associated Goal Target Group" />

  <Property
    name="hs_status"
    label="Status"
    type="enumeration"
    fieldType="select"
    description="The status of the Goal Target"
    options={[
  { label: "Exceeded", value: "exceeded" },
  { label: "Achieved", value: "achieved" },
  { label: "In progress", value: "in_progress" },
  { label: "Missed", value: "missed" },
  { label: "Pending", value: "pending" }
]}
  />

  <Property
    name="hs_outcome"
    label="Outcome"
    type="enumeration"
    fieldType="select"
    description="Goal Target outcome"
    options={[
  { label: "Completed", value: "completed" },
  { label: "Failed", value: "failed" },
  { label: "In progress", value: "in_progress" },
  { label: "Pending", value: "pending" }
]}
  />

  <Property
    name="hs_should_notify_on_kickoff"
    label="Notify on goal kickoff"
    type="enumeration"
    fieldType="booleancheckbox"
    description="Opt into notifications when a goal is kicked off"
    options={[
  { label: "Yes", value: "true" },
  { label: "No", value: "false" }
]}
  />

  <Property
    name="hs_should_notify_on_edit_updates"
    label="Notify with goal edit updates"
    type="enumeration"
    fieldType="booleancheckbox"
    description="Opt into goal edit update notifications"
    options={[
  { label: "Yes", value: "true" },
  { label: "No", value: "false" }
]}
  />

  <Property
    name="hs_should_notify_on_exceeded"
    label="Notify on goal exceeded"
    type="enumeration"
    fieldType="booleancheckbox"
    description="Opt into notifications when goal is exceeded"
    options={[
  { label: "Yes", value: "true" },
  { label: "No", value: "false" }
]}
  />

  <Property
    name="hs_should_notify_on_achieved"
    label="Notify on goal achieved"
    type="enumeration"
    fieldType="booleancheckbox"
    description="Opt into notifications when goal is achieved"
    options={[
  { label: "Yes", value: "true" },
  { label: "No", value: "false" }
]}
  />

  <Property
    name="hs_should_notify_on_missed"
    label="Notify on goal missed"
    type="enumeration"
    fieldType="booleancheckbox"
    description="Opt into notifications when a goal is missed"
    options={[
  { label: "Yes", value: "true" },
  { label: "No", value: "false" }
]}
  />

  <Property
    name="hs_should_notify_on_progress_updates"
    label="Notify with progress updates"
    type="enumeration"
    fieldType="booleancheckbox"
    description="Opt into goal progress updates notifications"
    options={[
  { label: "Yes", value: "true" },
  { label: "No", value: "false" }
]}
  />

  <Property name="hubspot_owner_id" label="Owner" type="enumeration" fieldType="select" description="The owner of the object." />

  <Property name="hs_owner_ids_of_all_owners" label="Owner ids of all owners" type="enumeration" fieldType="checkbox" description="The owner IDs of all owners of this object" />

  <Property name="hs_user_ids_of_all_owners" label="User IDs of all owners" type="enumeration" fieldType="checkbox" description="The user IDs of all owners of this record." />

  <Property
    name="hs_is_forecastable"
    label="Is forecastable"
    type="enumeration"
    fieldType="booleancheckbox"
    description="Whether the goal can be used for forecasting. Set to true for forecast goals"
    options={[
  { label: "Yes", value: "true" },
  { label: "No", value: "false" }
]}
  />

  <Property name="hs_template_id" label="Template ID" type="number" fieldType="number" description="ID of the template used to create the goal target, if applicable.  HS-defined templates use GoalType enum ordinals for the ID (see HsTemplateFactory)." />
</PropertyDefinitions>
