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

# Aircall

> 70 actions available for Aircall through StackOne. Use via Actions RPC, Toolset SDK, MCP, or A2A.

export const ConnectorEvents = ({webhookGuide, connectorName, variant = 'page'}) => {
  const HEADINGS = {
    page: 'Webhook Events',
    'next-step': 'Next Steps'
  };
  if (!webhookGuide) {
    return null;
  }
  return <>
      <h2>{HEADINGS[variant] ?? HEADINGS.page}</h2>
      <Columns cols={2}>
        <Card title="Webhooks setup" href={`/${webhookGuide}`}>
          <p style={{
    fontSize: '14px',
    marginTop: 0,
    marginBottom: 0
  }} className="connector-page-auth-description">
            Configure receiving Events for {connectorName} into StackOne.
          </p>
        </Card>
      </Columns>
    </>;
};

export const ConnectorReferences = ({references}) => {
  if (!Array.isArray(references) || references.length === 0) return null;
  return <>
      <h2>References</h2>
      <Columns cols={2}>
        {references.map(ref => {
    let safeHref;
    try {
      const parsed = new URL(ref.url);
      safeHref = parsed.protocol === 'http:' || parsed.protocol === 'https:' ? ref.url : undefined;
    } catch {
      safeHref = undefined;
    }
    return <Card key={`${ref.title}-${ref.url}`} title={ref.title} href={safeHref}>
              {ref.description}
            </Card>;
  })}
      </Columns>
    </>;
};

export const GettingStarted = ({connector}) => {
  const linkStyle = {
    textDecoration: 'none'
  };
  const connectorProfileGuides = connector?.authentication?.filter(a => a?.setupGuide) ?? [];
  const linkAccountGuides = connector?.authentication?.filter(a => a?.configGuide) ?? [];
  return <div style={{
    marginTop: '32px',
    paddingTop: '24px'
  }} className="getting-started-section">
      <div style={{
    fontSize: '20px',
    fontWeight: '600',
    marginBottom: '12px'
  }}>Getting Started</div>
      <Steps>
        <Step title="Create or Select a Project">
          Set up a new project or select an existing one. See the <a href="/guides/managing-projects" style={linkStyle}>Projects Guide</a>.
        </Step>
        <Step title="Configure the Connector">
          <>
            Enable the connector and set up its connector profile in your project. See <a href="/guides/explore-connectors" style={linkStyle}>Managing Connectors</a>.
            {connectorProfileGuides.length > 0 && <>
              <Columns cols={2}>
                {connectorProfileGuides.map(auth => <Card title="Connector Profile" href={`/${auth.setupGuide}`} icon={connector.icon} horizontal>
                    {connector.name} - {auth.label}
                  </Card>)}
              </Columns>
              </>}
          </>
        </Step>
        <Step title="Link an Account">
          <>
            Connect an account using <a href="/guides/embedding-stackone-hub" style={linkStyle}>StackOne Hub</a> or <a href="/guides/auth-link" style={linkStyle}>Auth Link</a>.
            {linkAccountGuides.length > 0 && <>
                <Columns cols={2}>
                  {linkAccountGuides.map(auth => <Card title="Link Account" href={`/${auth.configGuide}`} icon={connector.icon} horizontal>
                      {connector.name} - {auth.label}
                    </Card>)}
                </Columns>
              </>}
          </>
        </Step>
        <Step title="Use Actions">
          <>
            Invoke actions using one of the methods below:
            <ul style={{
    marginTop: '8px',
    paddingLeft: '20px'
  }}>
              <li style={{
    marginBottom: '4px'
  }}><a href="/mcp/quickstart" style={linkStyle}>MCP</a> – Model Context Protocol for AI assistants</li>
              <li style={{
    marginBottom: '4px'
  }}><a href="/a2a/quickstart" style={linkStyle}>A2A</a> – Agent-to-Agent protocol</li>
              <li style={{
    marginBottom: '4px'
  }}><a href="/agents/typescript/introduction" style={linkStyle}>AI Toolset (TypeScript)</a> – TypeScript SDK for AI agents</li>
              <li style={{
    marginBottom: '4px'
  }}><a href="/agents/python/introduction" style={linkStyle}>AI Toolset (Python)</a> – Python SDK for AI agents</li>
              <li style={{
    marginBottom: '4px'
  }}><a href="/platform/api-reference/actions/make-an-rpc-call-to-an-action" style={linkStyle}>Actions RPC</a> – Direct API calls</li>
              <li style={{
    marginBottom: '4px'
  }}><a href="/guides/playground" style={linkStyle}>Playground</a> – Test actions in the dashboard</li>
            </ul>
          </>
        </Step>
      </Steps>
    </div>;
};

export const MetaLibrary = ({title, noun, itemColumnHeader, columnHeader, filterLabel, filterSearchPlaceholder, search, setSearch, filtered, sharedStyles = {}, KeyCell, ValueCell, renderBadge, availableFilterValues, selectedFilterValues, setSelectedFilterValues}) => {
  const libraryStyles = {
    section: {
      marginTop: '24px',
      marginBottom: '16px'
    },
    sectionTitle: {
      fontSize: '18px',
      fontWeight: '600',
      marginBottom: '12px'
    },
    filterRow: {
      display: 'flex',
      gap: '12px',
      marginBottom: '12px',
      alignItems: 'stretch'
    },
    count: {
      fontSize: '12px',
      marginBottom: '8px'
    },
    tableContainer: {
      maxHeight: '500px',
      overflowY: 'auto',
      overflowX: 'auto',
      borderRadius: '8px',
      fontSize: '13px'
    },
    gridTable: {
      display: 'grid',
      minWidth: '600px',
      gridTemplateColumns: '200px 1fr'
    },
    gridTableWithColumn: {
      gridTemplateColumns: '200px 1fr 150px'
    },
    gridHeader: {
      display: 'contents'
    },
    gridHeaderCell: {
      position: 'sticky',
      top: 0,
      padding: '10px 12px',
      fontWeight: '600',
      zIndex: 1
    },
    gridRow: {
      display: 'contents'
    },
    gridCellItem: {
      padding: '10px 12px',
      fontWeight: '500'
    },
    gridCellValue: {
      padding: '10px 12px',
      fontSize: '12px'
    },
    gridCellDescription: {
      padding: '10px 12px'
    }
  };
  const styles = {
    ...libraryStyles,
    ...sharedStyles
  };
  const safeAvailable = Array.isArray(availableFilterValues) ? availableFilterValues : [];
  const safeSelected = Array.isArray(selectedFilterValues) ? selectedFilterValues : [];
  const hasColumn = safeAvailable.length > 0;
  const hasFilter = hasColumn && typeof setSelectedFilterValues === 'function';
  const ValueCellComponent = ValueCell || (() => null);
  return <div style={styles.section}>
      <div style={styles.sectionTitle}>{title}</div>
      <div style={styles.filterRow}>
        <SearchBar value={search} onChange={setSearch} placeholder={`Search ${noun}s`} />
        {hasFilter && <FilterDropdown label={filterLabel} items={safeAvailable} selectedItems={safeSelected} onChange={setSelectedFilterValues} searchPlaceholder={filterSearchPlaceholder} emptyLabel={`No ${filterLabel.toLowerCase()} found`} />}
      </div>
      <div style={styles.count} className="meta-library-count">
        {filtered.length === 0 ? `0 ${noun}s found` : `${filtered.length} ${noun}${filtered.length !== 1 ? 's' : ''}`}
      </div>
      <div className="not-prose meta-library-table-container" style={styles.tableContainer}>
        <div style={{
    ...hasColumn ? {
      ...styles.gridTable,
      ...styles.gridTableWithColumn
    } : styles.gridTable
  }}>
          <div style={styles.gridHeader}>
            <div style={styles.gridHeaderCell} className="meta-library-grid-header-cell">{itemColumnHeader}</div>
            <div style={styles.gridHeaderCell} className="meta-library-grid-header-cell">Description</div>
            {hasColumn && <div style={styles.gridHeaderCell} className="meta-library-grid-header-cell">{columnHeader}</div>}
          </div>
          {filtered.map(item => <div key={item.id} style={styles.gridRow}>
              <div style={styles.gridCellItem} className="meta-library-grid-cell">
                <div>{item.label}</div>
                <div style={{
    marginTop: '4px'
  }}>
                  <KeyCell id={item.id} />
                </div>
                {renderBadge ? renderBadge(item) : null}
              </div>
              <div style={styles.gridCellDescription} className="meta-library-grid-cell meta-library-grid-cell--description">{item.description}</div>
              {hasColumn && <div style={styles.gridCellValue} className="meta-library-grid-cell meta-library-grid-cell--values">
                  <ValueCellComponent item={item} />
                </div>}
            </div>)}
        </div>
      </div>
    </div>;
};

export const FilterDropdown = ({label, items, selectedItems, onChange, searchPlaceholder = 'Search...', emptyLabel = 'No items found', formatLabel}) => {
  const [dropdownOpen, setDropdownOpen] = React.useState(false);
  const [search, setSearch] = React.useState('');
  const [hoveredItem, setHoveredItem] = React.useState(null);
  const dropdownRef = React.useRef(null);
  const styles = {
    dropdownContainer: {
      position: 'relative'
    },
    dropdownTrigger: {
      display: 'flex',
      alignItems: 'center',
      gap: '8px',
      padding: '10px 14px',
      borderRadius: '8px',
      fontSize: '14px',
      cursor: 'pointer',
      whiteSpace: 'nowrap',
      minWidth: '160px',
      justifyContent: 'space-between'
    },
    dropdownMenu: {
      position: 'absolute',
      top: '100%',
      right: 0,
      marginTop: '4px',
      borderRadius: '8px',
      zIndex: 50,
      minWidth: '220px',
      maxHeight: '320px',
      display: 'flex',
      flexDirection: 'column'
    },
    dropdownHeader: {
      padding: '8px 12px'
    },
    selectActions: {
      display: 'flex',
      alignItems: 'center',
      gap: '8px',
      marginTop: '6px',
      fontSize: '12px'
    },
    selectActionBtn: {
      background: 'none',
      border: 'none',
      cursor: 'pointer',
      padding: '2px 4px',
      fontSize: '12px'
    },
    dropdownSearchInput: {
      width: '100%',
      padding: '8px 10px',
      borderRadius: '6px',
      fontSize: '13px',
      outline: 'none'
    },
    dropdownList: {
      overflowY: 'auto',
      maxHeight: '220px',
      padding: '4px 0'
    },
    dropdownItem: {
      display: 'flex',
      alignItems: 'center',
      gap: '10px',
      padding: '8px 12px',
      cursor: 'pointer',
      fontSize: '13px',
      transition: 'background-color 0.1s'
    },
    checkbox: {
      width: '16px',
      height: '16px',
      borderRadius: '4px',
      display: 'flex',
      alignItems: 'center',
      justifyContent: 'center',
      flexShrink: 0
    },
    checkmark: {
      color: 'white',
      fontSize: '10px',
      fontWeight: 'bold'
    },
    dropdownFooter: {
      padding: '8px 12px',
      display: 'flex',
      justifyContent: 'space-between',
      alignItems: 'center'
    },
    clearButton: {
      fontSize: '12px',
      cursor: 'pointer',
      padding: '4px 8px',
      borderRadius: '4px',
      border: 'none',
      background: 'none'
    },
    badge: {
      fontSize: '11px',
      fontWeight: '600',
      padding: '2px 6px',
      borderRadius: '10px',
      marginLeft: '4px'
    },
    chevron: {
      fontSize: '10px',
      transition: 'transform 0.15s'
    },
    noResults: {
      padding: '12px',
      textAlign: 'center',
      fontSize: '13px'
    }
  };
  const safeSelected = Array.isArray(selectedItems) ? selectedItems : [];
  const formatItemLabel = item => {
    if (typeof formatLabel === 'function') {
      return formatLabel(item);
    }
    return item;
  };
  const filteredItems = React.useMemo(() => {
    if (!search) return items;
    const searchLower = search.toLowerCase();
    return items.filter(item => {
      const labelText = formatItemLabel(item);
      return labelText.toLowerCase().includes(searchLower);
    });
  }, [items, search, formatLabel]);
  const isSelected = item => safeSelected.includes(item);
  const toggleItem = item => {
    const next = isSelected(item) ? safeSelected.filter(v => v !== item) : [...safeSelected, item];
    onChange(next);
  };
  const clearFilters = () => {
    onChange([]);
  };
  const selectAll = () => {
    onChange(items);
  };
  React.useEffect(() => {
    const handleClickOutside = e => {
      if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
        setDropdownOpen(false);
        setSearch('');
        setHoveredItem(null);
      }
    };
    document.addEventListener('mousedown', handleClickOutside);
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, []);
  return <div style={styles.dropdownContainer} ref={dropdownRef}>
      <button type="button" onClick={() => setDropdownOpen(!dropdownOpen)} style={styles.dropdownTrigger} className={`filter-dropdown__trigger${safeSelected.length > 0 ? ' filter-dropdown__trigger--active' : ''}`}>
        <span>
          {label}
          {safeSelected.length > 0 && <span style={styles.badge} className="filter-dropdown__badge">{safeSelected.length}</span>}
        </span>
        <span style={{
    ...styles.chevron,
    transform: dropdownOpen ? 'rotate(180deg)' : 'rotate(0deg)'
  }} className="filter-dropdown__chevron">
          ▼
        </span>
      </button>
      {dropdownOpen && <div style={styles.dropdownMenu} className="filter-dropdown__menu">
          <div style={styles.dropdownHeader} className="filter-dropdown__header">
            <input type="text" placeholder={searchPlaceholder} value={search} onChange={e => setSearch(e.target.value)} style={styles.dropdownSearchInput} className="filter-dropdown__search" autoFocus />
            <div style={styles.selectActions}>
              <button type="button" onClick={selectAll} style={styles.selectActionBtn} className="filter-dropdown__action-btn">
                Select all
              </button>
              <span className="filter-dropdown__separator">|</span>
              <button type="button" onClick={clearFilters} style={styles.selectActionBtn} className="filter-dropdown__action-btn">
                Clear
              </button>
            </div>
          </div>
          <div style={styles.dropdownList}>
            {filteredItems.length === 0 ? <div style={styles.noResults} className="filter-dropdown__no-results">{emptyLabel}</div> : filteredItems.map(item => {
    const itemClass = ['filter-dropdown__item', hoveredItem === item ? 'filter-dropdown__item--hovered' : '', isSelected(item) ? 'filter-dropdown__item--selected' : ''].filter(Boolean).join(' ');
    const checkboxClass = `filter-dropdown__checkbox${isSelected(item) ? ' filter-dropdown__checkbox--checked' : ''}`;
    return <div key={item} onClick={() => toggleItem(item)} onMouseEnter={() => setHoveredItem(item)} onMouseLeave={() => setHoveredItem(null)} style={styles.dropdownItem} className={itemClass}>
                    <div style={styles.checkbox} className={checkboxClass}>
                      {isSelected(item) && <span style={styles.checkmark}>✓</span>}
                    </div>
                    <span>{formatItemLabel(item)}</span>
                  </div>;
  })}
          </div>
        </div>}
    </div>;
};

export const SearchBar = ({value, onChange, placeholder = 'Search...'}) => {
  const baseStyle = {
    padding: '10px 14px',
    borderRadius: '8px',
    fontSize: '14px',
    outline: 'none',
    flex: 1,
    minWidth: 0
  };
  return <input type="text" placeholder={placeholder} value={value} onChange={e => onChange(e.target.value)} style={baseStyle} className="search-bar" />;
};

export const ConnectorPage = ({connector}) => {
  const styles = {
    header: {
      display: 'flex',
      alignItems: 'center',
      gap: '12px',
      marginBottom: '24px'
    },
    tagsRow: {
      display: 'flex',
      flexWrap: 'wrap',
      gap: '6px',
      marginTop: '8px'
    },
    releaseTag: {
      display: 'inline-block',
      padding: '2px 8px',
      borderRadius: '4px',
      fontSize: '11px',
      fontWeight: '500'
    },
    categoryTag: {
      display: 'inline-block',
      padding: '2px 8px',
      borderRadius: '4px',
      fontSize: '11px',
      fontWeight: '500'
    },
    icon: {
      width: '48px',
      height: '48px',
      borderRadius: '10px',
      padding: '2px'
    },
    title: {
      fontSize: '24px',
      fontWeight: '600'
    },
    subtitle: {
      fontSize: '14px'
    },
    authDescription: {
      fontSize: '14px',
      marginTop: 0
    },
    sectionTitle: {
      fontSize: '18px',
      fontWeight: '600',
      marginBottom: '12px'
    },
    codeWrapper: {
      position: 'relative',
      display: 'inline-flex',
      alignItems: 'center',
      maxWidth: '100%',
      cursor: 'pointer',
      overflowX: 'auto',
      overflowY: 'hidden',
      msOverflowStyle: 'none',
      scrollbarWidth: 'none'
    },
    code: {
      padding: '4px 8px',
      borderRadius: '4px',
      fontSize: '11px',
      display: 'inline-block',
      whiteSpace: 'nowrap',
      transition: 'background-color 0.15s'
    },
    tooltip: {
      position: 'absolute',
      top: '100%',
      left: '50%',
      transform: 'translateX(-50%)',
      padding: '6px 10px',
      borderRadius: '6px',
      fontSize: '11px',
      whiteSpace: 'nowrap',
      marginTop: '6px',
      zIndex: 50,
      maxWidth: '300px',
      wordBreak: 'break-all'
    },
    tooltipArrow: {
      position: 'absolute',
      bottom: '100%',
      left: '50%',
      transform: 'translateX(-50%)',
      borderWidth: '5px',
      borderStyle: 'solid',
      zIndex: 50
    }
  };
  const [search, setSearch] = React.useState('');
  const [copiedId, setCopiedId] = React.useState(null);
  const [selectedScopes, setSelectedScopes] = React.useState([]);
  const [eventSearch, setEventSearch] = React.useState('');
  const [selectedTags, setSelectedTags] = React.useState([]);
  const events = Array.isArray(connector.events) ? connector.events : [];
  const availableScopes = React.useMemo(() => {
    const set = new Set();
    connector.actions.forEach(a => {
      if (Array.isArray(a.requiredScopes)) {
        a.requiredScopes.forEach(s => {
          if (s) set.add(s);
        });
      }
    });
    return Array.from(set).sort();
  }, [connector.actions]);
  const filtered = React.useMemo(() => {
    const searchLower = search.toLowerCase();
    return connector.actions.filter(a => {
      const matchesSearch = a.label.toLowerCase().includes(searchLower) || a.description.toLowerCase().includes(searchLower) || a.id.toLowerCase().includes(searchLower);
      if (!matchesSearch) return false;
      if (selectedScopes.length === 0) return true;
      const scopes = Array.isArray(a.requiredScopes) ? a.requiredScopes : [];
      if (scopes.length === 0) return false;
      return selectedScopes.some(scope => scopes.includes(scope));
    });
  }, [connector.actions, search, selectedScopes]);
  const availableTags = React.useMemo(() => {
    const set = new Set();
    events.forEach(e => {
      if (Array.isArray(e.tags)) {
        e.tags.forEach(t => {
          if (t) set.add(t);
        });
      }
    });
    return Array.from(set).sort();
  }, [events]);
  const filteredEvents = React.useMemo(() => {
    const searchLower = eventSearch.toLowerCase();
    return events.filter(e => {
      const matchesSearch = e.label.toLowerCase().includes(searchLower) || e.description.toLowerCase().includes(searchLower) || e.id.toLowerCase().includes(searchLower);
      if (!matchesSearch) return false;
      if (selectedTags.length === 0) return true;
      const tags = Array.isArray(e.tags) ? e.tags : [];
      if (tags.length === 0) return false;
      return selectedTags.some(tag => tags.includes(tag));
    });
  }, [events, eventSearch, selectedTags]);
  const handleImageError = e => {
    e.target.style.display = 'none';
  };
  const formatCategoryLabel = cat => {
    const acronyms = ['ai', 'ats', 'crm', 'hris', 'iam', 'lms'];
    if (acronyms.includes(cat.toLowerCase())) {
      return cat.toUpperCase();
    }
    return cat.replace(/_/g, ' ').replace(/\b\w/g, c => c.toUpperCase());
  };
  const ReleaseTag = () => {
    if (!connector.releaseStage || connector.releaseStage === 'ga') return null;
    const variantClass = connector.releaseStage === 'beta' ? 'connector-page-tag-beta' : 'connector-page-tag-preview';
    return <span style={styles.releaseTag} className={variantClass}>
        {connector.releaseStage.charAt(0).toUpperCase() + connector.releaseStage.slice(1)}
      </span>;
  };
  const CategoryTags = () => {
    if (!connector.categories || connector.categories.length === 0) return null;
    return <>
        {connector.categories.map(cat => <span key={cat} style={styles.categoryTag} className="connector-page-category-tag">
            {formatCategoryLabel(cat)}
          </span>)}
      </>;
  };
  const copyToClipboard = async (text, id) => {
    try {
      await navigator.clipboard.writeText(text);
      setCopiedId(id);
      setTimeout(() => setCopiedId(null), 1500);
    } catch (err) {
      console.error('Failed to copy:', err);
    }
  };
  const CopyChip = ({text, copyId}) => {
    const [isHovered, setIsHovered] = React.useState(false);
    const isCopied = copiedId === copyId;
    if (!text) {
      return null;
    }
    const codeClassName = `connector-page-code${isCopied ? ' connector-page-code--copied' : ''}`;
    return <div style={styles.codeWrapper} onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)} onClick={() => copyToClipboard(text, copyId)} title="">
        {(isHovered || isCopied) && <div style={styles.tooltip} className="connector-page-tooltip">
            {isCopied ? '✓ Copied!' : 'Click to copy'}
            <div style={styles.tooltipArrow} className="connector-page-tooltip-arrow" />
          </div>}
        <code style={styles.code} className={codeClassName}>
          {text}
        </code>
      </div>;
  };
  const KeyCell = ({id}) => <CopyChip text={id} copyId={id} />;
  const ActionScopesCell = ({item}) => {
    const scopeList = Array.isArray(item.requiredScopes) ? item.requiredScopes.filter(Boolean) : [];
    if (scopeList.length === 0) return null;
    return <div style={{
      display: 'flex',
      flexWrap: 'wrap',
      gap: '6px'
    }}>
        {scopeList.map(scope => <CopyChip key={scope} text={scope} copyId={`scopes:${item.id}:${scope}`} />)}
      </div>;
  };
  const EventTagsCell = ({item}) => {
    const tagList = Array.isArray(item.tags) ? item.tags.filter(Boolean) : [];
    if (tagList.length === 0) return null;
    return <div style={{
      display: 'flex',
      flexWrap: 'wrap',
      gap: '6px'
    }}>
        {tagList.map(tag => <span key={tag} style={styles.categoryTag} className="connector-page-category-tag">
            {tag}
          </span>)}
      </div>;
  };
  const renderEventBadge = item => {
    if (!item.requiresManualSetup) return null;
    return <div style={{
      marginTop: '4px'
    }}>
        <span style={styles.categoryTag} className="connector-page-category-tag">
          Manual setup
        </span>
      </div>;
  };
  return <div>
      {}
      <div style={styles.header}>
        <img src={connector.icon} alt={connector.name} style={styles.icon} className="connector-page-icon" onError={handleImageError} />
        <div>
          <div style={styles.title}>{connector.name}</div>
          <div style={styles.subtitle} className="connector-page-subtitle">
            {connector.actions.length} actions · {events.length > 0 ? `${events.length} event${events.length !== 1 ? 's' : ''} · ` : ''}{connector.authentication.length} auth method{connector.authentication.length !== 1 ? 's' : ''}
          </div>
          {connector.releaseStage && connector.releaseStage !== 'ga' || connector.categories && connector.categories.length > 0 ? <div style={styles.tagsRow}>
              <ReleaseTag />
              <CategoryTags />
            </div> : null}
        </div>
      </div>

      {}
      <div style={styles.sectionTitle}>Authentication</div>
      <Columns cols={2}>
        {connector.authentication.length > 0 ? connector.authentication.map(auth => {
    const authLabel = auth?.label || '';
    const authDescription = auth?.description;
    const configGuide = auth?.configGuide;
    const setupGuide = auth?.setupGuide;
    const hasConfigGuide = !!configGuide;
    const hasSetupGuide = !!setupGuide;
    const hasAnyGuide = hasConfigGuide || hasSetupGuide;
    return <Card key={authLabel} title={authLabel}>
                {authDescription && <p style={{
      ...styles.authDescription,
      marginBottom: hasAnyGuide ? '8px' : 0
    }} className="connector-page-auth-description">
                    {authDescription}
                  </p>}
                {hasAnyGuide && <span style={{
      fontSize: '14px'
    }}>
                    Guides: {hasSetupGuide && <a href={`/${setupGuide}`} style={{
      textDecoration: 'none'
    }}>Connector Profile</a>}
                    {hasConfigGuide && hasSetupGuide && ', '}
                    {hasConfigGuide && <a href={`/${configGuide}`} style={{
      textDecoration: 'none'
    }}>Link Account</a>}
                  </span>}
              </Card>;
  }) : <>
            Contact StackOne for authentication details.
          </>}
      </Columns>

      <ConnectorEvents webhookGuide={connector.webhookGuide} connectorName={connector.name} />

      <MetaLibrary title="Actions" noun="action" itemColumnHeader="Action" columnHeader="Required scopes" filterLabel="Scopes" filterSearchPlaceholder="Search scopes..." search={search} setSearch={setSearch} filtered={filtered} sharedStyles={{
    sectionTitle: styles.sectionTitle
  }} KeyCell={KeyCell} ValueCell={ActionScopesCell} availableFilterValues={availableScopes} selectedFilterValues={selectedScopes} setSelectedFilterValues={setSelectedScopes} />

      {events.length > 0 && <MetaLibrary title="Events" noun="event" itemColumnHeader="Event" columnHeader="Tags" filterLabel="Tags" filterSearchPlaceholder="Search tags..." search={eventSearch} setSearch={setEventSearch} filtered={filteredEvents} sharedStyles={{
    sectionTitle: styles.sectionTitle
  }} KeyCell={KeyCell} ValueCell={EventTagsCell} renderBadge={renderEventBadge} availableFilterValues={availableTags} selectedFilterValues={selectedTags} setSelectedFilterValues={setSelectedTags} />}

      <GettingStarted connector={connector} />

      <ConnectorReferences references={connector.documentation?.references} />

    </div>;
};

export const connector = {
  "key": "aircall",
  "name": "Aircall",
  "icon": "https://stackone-logos.com/api/aircall/filled/png",
  "authentication": [{
    "label": "API Key",
    "description": "Admin privileges are required in your Aircall dashboard to generate an API key.",
    "configGuide": "connectors/aircall/guides/link-account/api-key",
    "setupGuide": "connectors/aircall/guides/connector-profile/api-key"
  }],
  "actions": [{
    "id": "aircall_ping",
    "label": "Ping",
    "description": "Verify API connectivity and authentication with the Aircall Public API."
  }, {
    "id": "aircall_retrieve_company_information",
    "label": "Get Company",
    "description": "Retrieve information about the Aircall company associated with the authenticated account."
  }, {
    "id": "aircall_list_all_users_v2",
    "label": "List Users V2",
    "description": "Retrieve a paginated list of users using the Aircall V2 users endpoint."
  }, {
    "id": "aircall_retrieve_a_user_v2",
    "label": "Get User V2",
    "description": "Retrieve a single user using the Aircall V2 endpoint."
  }, {
    "id": "aircall_create_a_user_v2",
    "label": "Create User V2",
    "description": "Create a new user using the Aircall V2 endpoint."
  }, {
    "id": "aircall_update_a_user_v2",
    "label": "Update User V2",
    "description": "Update an existing user using the Aircall V2 endpoint."
  }, {
    "id": "aircall_list_all_numbers_for_a_user_v2",
    "label": "List Numbers For User V2",
    "description": "Retrieve all numbers assigned to a specific user (V2)."
  }, {
    "id": "aircall_delete_a_user",
    "label": "Delete User",
    "description": "Delete an Aircall user."
  }, {
    "id": "aircall_retrieve_list_of_users_availability",
    "label": "List Users Availabilities",
    "description": "Retrieve the availability status of all users."
  }, {
    "id": "aircall_check_availability_of_a_user",
    "label": "Get User Availability",
    "description": "Check the current availability of a single user."
  }, {
    "id": "aircall_start_an_outbound_call",
    "label": "Start Outbound Call",
    "description": "Initiate an outbound call from a user's Aircall Phone."
  }, {
    "id": "aircall_dial_a_phone_number_in_the_phone",
    "label": "Dial Phone Number",
    "description": "Pre-fill a phone number in a user's Aircall Phone dialer. The target user must be signed in to the Aircall Phone app."
  }, {
    "id": "aircall_list_all_teams",
    "label": "List Teams",
    "description": "Retrieve a paginated list of teams in the company."
  }, {
    "id": "aircall_retrieve_a_team",
    "label": "Get Team",
    "description": "Retrieve a single team by ID."
  }, {
    "id": "aircall_create_a_team",
    "label": "Create Team",
    "description": "Create a new team in the company."
  }, {
    "id": "aircall_delete_a_team",
    "label": "Delete Team",
    "description": "Delete a team from the company."
  }, {
    "id": "aircall_add_a_user_to_a_team",
    "label": "Add User To Team",
    "description": "Add a user to an existing team."
  }, {
    "id": "aircall_remove_a_user_from_a_team",
    "label": "Remove User From Team",
    "description": "Remove a user from a team."
  }, {
    "id": "aircall_list_all_calls",
    "label": "List Calls",
    "description": "Retrieve a paginated list of calls in the company."
  }, {
    "id": "aircall_retrieve_a_call",
    "label": "Get Call",
    "description": "Retrieve a single call by ID."
  }, {
    "id": "aircall_search_calls",
    "label": "Search Calls",
    "description": "Search calls by phone number, user, tags, or other filters."
  }, {
    "id": "aircall_comment_a_call",
    "label": "Comment Call",
    "description": "Add a comment to a call."
  }, {
    "id": "aircall_tag_a_call",
    "label": "Tag Call",
    "description": "Apply one or more tags to a call."
  }, {
    "id": "aircall_archive_a_call",
    "label": "Archive Call",
    "description": "Archive a call."
  }, {
    "id": "aircall_unarchive_a_call",
    "label": "Unarchive Call",
    "description": "Unarchive a previously archived call."
  }, {
    "id": "aircall_delete_call_recording",
    "label": "Delete Call Recording",
    "description": "Delete the recording of a call."
  }, {
    "id": "aircall_delete_call_voicemail",
    "label": "Delete Call Voicemail",
    "description": "Delete the voicemail recording of a call."
  }, {
    "id": "aircall_insight_cards",
    "label": "Create Call Insight Card",
    "description": "Attach an Insight Card to a call."
  }, {
    "id": "aircall_retrieve_a_transcription",
    "label": "Get Call Transcription",
    "description": "Retrieve the transcription of a call."
  }, {
    "id": "aircall_retrieve_realtime_transcription",
    "label": "Get Call Realtime Transcription",
    "description": "Retrieve the realtime transcription of an ongoing call."
  }, {
    "id": "aircall_retrieve_sentiments",
    "label": "Get Call Sentiments",
    "description": "Retrieve sentiment analysis for a call."
  }, {
    "id": "aircall_retrieve_topics",
    "label": "Get Call Topics",
    "description": "Retrieve detected topics for a call."
  }, {
    "id": "aircall_retrieve_a_summary",
    "label": "Get Call Summary",
    "description": "Retrieve the AI-generated summary for a call."
  }, {
    "id": "aircall_retrieve_a_custom_summary_result",
    "label": "Get Call Custom Summary Result",
    "description": "Retrieve a custom summary result for a call."
  }, {
    "id": "aircall_retrieve_action_items",
    "label": "Get Call Action Items",
    "description": "Retrieve AI-extracted action items for a call."
  }, {
    "id": "aircall_retrieve_a_playbook_result",
    "label": "Get Call Playbook Result",
    "description": "Retrieve playbook evaluation result for a call."
  }, {
    "id": "aircall_retrieve_call_evaluations",
    "label": "Get Call Evaluations",
    "description": "Retrieve evaluations submitted for a call."
  }, {
    "id": "aircall_list_all_numbers",
    "label": "List Numbers",
    "description": "Retrieve a paginated list of numbers provisioned on the Aircall account."
  }, {
    "id": "aircall_retrieve_a_number",
    "label": "Get Number",
    "description": "Retrieve a single Aircall number by ID."
  }, {
    "id": "aircall_update_a_number",
    "label": "Update Number",
    "description": "Update an Aircall number's settings."
  }, {
    "id": "aircall_update_music_and_messages",
    "label": "Update Music And Messages",
    "description": "Update a number's music and messages URLs."
  }, {
    "id": "aircall_registration_status",
    "label": "Registration Status",
    "description": "Fetch compliance status for A2P 10DLC and toll-free messaging registration for a specific number."
  }, {
    "id": "aircall_list_all_contacts",
    "label": "List Contacts",
    "description": "Retrieve a paginated list of contacts in the Aircall address book."
  }, {
    "id": "aircall_search_contacts",
    "label": "Search Contacts",
    "description": "Search contacts by phone number or email."
  }, {
    "id": "aircall_retrieve_a_contact",
    "label": "Get Contact",
    "description": "Retrieve a single contact by ID."
  }, {
    "id": "aircall_create_a_contact",
    "label": "Create Contact",
    "description": "Create a new contact in the address book."
  }, {
    "id": "aircall_update_a_contact",
    "label": "Update Contact",
    "description": "Update an existing contact."
  }, {
    "id": "aircall_delete_a_contact",
    "label": "Delete Contact",
    "description": "Delete a contact from the address book."
  }, {
    "id": "aircall_add_phone_number_to_a_contact",
    "label": "Add Phone Number To Contact",
    "description": "Add a new phone number to an existing contact."
  }, {
    "id": "aircall_update_a_phone_number_from_a_contact",
    "label": "Update Contact Phone Number",
    "description": "Update a phone number entry on a contact."
  }, {
    "id": "aircall_delete_a_phone_number_from_a_contact",
    "label": "Delete Contact Phone Number",
    "description": "Delete a phone number entry from a contact."
  }, {
    "id": "aircall_add_email_to_a_contact",
    "label": "Add Email To Contact",
    "description": "Add a new email address to a contact."
  }, {
    "id": "aircall_update_an_email_from_a_contact",
    "label": "Update Contact Email",
    "description": "Update an email entry on a contact."
  }, {
    "id": "aircall_delete_an_email_from_a_contact",
    "label": "Delete Contact Email",
    "description": "Delete an email entry from a contact."
  }, {
    "id": "aircall_list_all_tags",
    "label": "List Tags",
    "description": "Retrieve a paginated list of tags in the company."
  }, {
    "id": "aircall_retrieve_a_tag",
    "label": "Get Tag",
    "description": "Retrieve a single tag by ID."
  }, {
    "id": "aircall_create_a_tag",
    "label": "Create Tag",
    "description": "Create a new tag in the company."
  }, {
    "id": "aircall_update_a_tag",
    "label": "Update Tag",
    "description": "Update an existing tag."
  }, {
    "id": "aircall_delete_a_tag",
    "label": "Delete Tag",
    "description": "Delete a tag from the company."
  }, {
    "id": "aircall_list_all_webhooks",
    "label": "List Webhooks",
    "description": "Retrieve a paginated list of webhooks configured on the company."
  }, {
    "id": "aircall_retrieve_a_webhook",
    "label": "Get Webhook",
    "description": "Retrieve a single webhook by ID."
  }, {
    "id": "aircall_create_a_webhook",
    "label": "Create Webhook",
    "description": "Register a new webhook."
  }, {
    "id": "aircall_update_a_webhook",
    "label": "Update Webhook",
    "description": "Update an existing webhook."
  }, {
    "id": "aircall_delete_a_webhook",
    "label": "Delete Webhook",
    "description": "Delete a webhook."
  }, {
    "id": "aircall_retrieve_a_dialer_campaign",
    "label": "Get Dialer Campaign",
    "description": "Retrieve the active dialer campaign for a user."
  }, {
    "id": "aircall_create_a_dialer_campaign",
    "label": "Create Dialer Campaign",
    "description": "Create an active dialer campaign for a user."
  }, {
    "id": "aircall_delete_a_dialer_campaign",
    "label": "Delete Dialer Campaign",
    "description": "Delete the active dialer campaign for a user."
  }, {
    "id": "aircall_retrieve_phone_numbers",
    "label": "List Dialer Campaign Phone Numbers",
    "description": "Retrieve phone numbers attached to a user's dialer campaign."
  }, {
    "id": "aircall_add_phone_numbers",
    "label": "Add Dialer Campaign Phone Numbers",
    "description": "Add phone numbers to a user's dialer campaign."
  }, {
    "id": "aircall_delete_a_phone_number",
    "label": "Delete Dialer Campaign Phone Number",
    "description": "Remove a phone number from a user's dialer campaign."
  }],
  "events": [],
  "releaseStage": "preview",
  "categories": []
};

<ConnectorPage connector={connector} />
