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

# Historical Experience

> Career history and job change data — past roles, tenure, and professional trajectory.

export const RBCardGroup = ({cols = 3, children}) => <div className={`rb-grid-${cols}`}>{children}</div>;

export const RBCard = ({href, title, desc, icon, tag, children, stat}) => {
  const icons = {
    cloud: <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M2.25 15a4.5 4.5 0 0 0 4.5 4.5H18a3.75 3.75 0 0 0 1.332-7.257 3 3 0 0 0-3.758-3.848 5.25 5.25 0 0 0-10.233 2.33A4.502 4.502 0 0 0 2.25 15Z" />
      </svg>,
    database: <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M20.25 6.375c0 2.278-3.694 4.125-8.25 4.125S3.75 8.653 3.75 6.375m16.5 0c0-2.278-3.694-4.125-8.25-4.125S3.75 4.097 3.75 6.375m16.5 0v11.25c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125V6.375m16.5 5.625c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125" />
      </svg>,
    table: <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M3.375 19.5h17.25m-17.25 0a1.125 1.125 0 0 1-1.125-1.125M3.375 19.5h7.5c.621 0 1.125-.504 1.125-1.125m-9.75 0V5.625m0 12.75v-1.5c0-.621.504-1.125 1.125-1.125m18.375 2.625V5.625m0 12.75c0 .621-.504 1.125-1.125 1.125m1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125m0 3.75h-7.5A1.125 1.125 0 0 1 12 18.375m9.75-12.75c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125m19.5 0v1.5c0 .621-.504 1.125-1.125 1.125M2.25 5.625v1.5c0 .621.504 1.125 1.125 1.125m0 0h17.25m-17.25 0h7.5c.621 0 1.125.504 1.125 1.125M3.375 8.25c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125m17.25-3.75h-7.5c-.621 0-1.125.504-1.125 1.125m8.625-1.125c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125M12 10.875v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 10.875c0 .621.504 1.125 1.125 1.125m-2.25 0c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125m2.25-2.25h-2.25m2.25 0h2.25" />
      </svg>,
    link: <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M13.19 8.688a4.5 4.5 0 0 1 1.242 7.244l-4.5 4.5a4.5 4.5 0 0 1-6.364-6.364l1.757-1.757m13.35-.622 1.757-1.757a4.5 4.5 0 0 0-6.364-6.364l-4.5 4.5a4.5 4.5 0 0 0 1.242 7.244" />
      </svg>,
    clock: <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
      </svg>,
    'book-atlas': <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M12 6.042A8.967 8.967 0 0 0 6 3.75c-1.052 0-2.062.18-3 .512v14.25A8.987 8.987 0 0 1 6 18c2.305 0 4.408.867 6 2.292m0-14.25a8.966 8.966 0 0 1 6-2.292c1.052 0 2.062.18 3 .512v14.25A8.987 8.987 0 0 0 18 18a8.967 8.967 0 0 0-6 2.292m0-14.25v14.25" />
      </svg>,
    fingerprint: <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M7.864 4.243A7.5 7.5 0 0 1 19.5 10.5c0 2.92-.556 5.709-1.568 8.268M5.742 6.364A7.465 7.465 0 0 0 4.5 10.5a7.464 7.464 0 0 1-1.15 3.993m1.989 3.559A11.209 11.209 0 0 0 8.25 10.5a3.75 3.75 0 1 1 7.5 0c0 .527-.021 1.049-.064 1.565M12 10.5a14.94 14.94 0 0 1-3.6 9.75m6.633-4.596a18.666 18.666 0 0 1-2.485 5.33" />
      </svg>,
    'gauge-high': <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M12 3v2.25m6.364.386-1.591 1.591M21 12h-2.25m-.386 6.364-1.591-1.591M12 18.75V21m-4.773-4.227-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0Z" />
      </svg>,
    wrench: <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M11.42 15.17 17.25 21A2.652 2.652 0 0 0 21 17.25l-5.877-5.877M11.42 15.17l2.496-3.03c.317-.384.74-.626 1.208-.766M11.42 15.17l-4.655 5.653a2.548 2.548 0 1 1-3.586-3.586l6.837-5.63m5.108-.233c.55-.164 1.163-.188 1.743-.14a4.5 4.5 0 0 0 4.486-6.336l-3.276 3.277a3.004 3.004 0 0 1-2.25-2.25l3.276-3.276a4.5 4.5 0 0 0-6.336 4.486c.091 1.076-.071 2.264-.904 2.95l-.102.085m-1.745 1.437L5.909 7.5H4.5L3 3.75l1.5-1.5L8.25 3.75v1.409l4.26 4.26m-1.745 1.437 1.745-1.437m6.615 8.206L15.75 15.75M4.867 19.125h.008v.008h-.008v-.008Z" />
      </svg>,
    'magnifying-glass': <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 15.803 7.5 7.5 0 0 0 15.803 15.803Z" />
      </svg>,
    envelope: <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M21.75 6.75v10.5a2.25 2.25 0 0 1-2.25 2.25h-15a2.25 2.25 0 0 1-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0 0 19.5 4.5h-15a2.25 2.25 0 0 0-2.25 2.25m19.5 0v.243a2.25 2.25 0 0 1-1.07 1.916l-7.5 4.615a2.25 2.25 0 0 1-2.36 0L3.32 8.91a2.25 2.25 0 0 1-1.07-1.916V6.75" />
      </svg>,
    building: <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M2.25 21h19.5m-18-18v18m10.5-18v18m6-13.5V21M6.75 6.75h.75m-.75 3h.75m-.75 3h.75m3-6h.75m-.75 3h.75m-.75 3h.75M6.75 21v-3.375c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21M3 3h12m-.75 4.5H21m-3.75 3.75h.008v.008h-.008v-.008Zm0 3h.008v.008h-.008v-.008Zm0 3h.008v.008h-.008v-.008Z" />
      </svg>,
    user: <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M15.75 6a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0ZM4.501 20.118a7.5 7.5 0 0 1 14.998 0A17.933 17.933 0 0 1 12 21.75c-2.676 0-5.216-.584-7.499-1.632Z" />
      </svg>,
    users: <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M15 19.128a9.38 9.38 0 0 0 2.625.372 9.337 9.337 0 0 0 4.121-.952 4.125 4.125 0 0 0-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 0 1 8.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0 1 11.964-3.07M12 6.375a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0Zm8.25 2.25a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z" />
      </svg>,
    'user-group': <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M15 19.128a9.38 9.38 0 0 0 2.625.372 9.337 9.337 0 0 0 4.121-.952 4.125 4.125 0 0 0-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 0 1 8.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0 1 11.964-3.07M12 6.375a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0Zm8.25 2.25a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z" />
      </svg>,
    'users-gear': <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.325.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 0 1 0-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28Z" />
      </svg>,
    mobile: <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M10.5 1.5H8.25A2.25 2.25 0 0 0 6 3.75v16.5a2.25 2.25 0 0 0 2.25 2.25h7.5A2.25 2.25 0 0 0 18 20.25V3.75a2.25 2.25 0 0 0-2.25-2.25H13.5m-3 0V3h3V1.5m-3 0h3m-3 18h3" />
      </svg>,
    calendar: <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M6.75 3v2.25M17.25 3v2.25M3 18.75V7.5a2.25 2.25 0 0 1 2.25-2.25h13.5A2.25 2.25 0 0 1 21 7.5v11.25m-18 0A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75m-18 0v-7.5A2.25 2.25 0 0 1 5.25 9h13.5A2.25 2.25 0 0 1 21 11.25v7.5" />
      </svg>,
    'badge-check': <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M9 12.75 11.25 15 15 9.75M21 12c0 1.268-.63 2.39-1.593 3.068a3.745 3.745 0 0 1-1.043 3.296 3.745 3.745 0 0 1-3.296 1.043A3.745 3.745 0 0 1 12 21c-1.268 0-2.39-.63-3.068-1.593a3.746 3.746 0 0 1-3.296-1.043 3.745 3.745 0 0 1-1.043-3.296A3.745 3.745 0 0 1 3 12c0-1.268.63-2.39 1.593-3.068a3.745 3.745 0 0 1 1.043-3.296 3.746 3.746 0 0 1 3.296-1.043A3.746 3.746 0 0 1 12 3c1.268 0 2.39.63 3.068 1.593a3.746 3.746 0 0 1 3.296 1.043 3.746 3.746 0 0 1 1.043 3.296A3.745 3.745 0 0 1 21 12Z" />
      </svg>,
    at: <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M16.5 12a4.5 4.5 0 1 1-9 0 4.5 4.5 0 0 1 9 0Zm0 0c0 1.657 1.007 3 2.25 3S21 13.657 21 12a9 9 0 1 0-2.636 6.364M16.5 12V8.25" />
      </svg>,
    handshake: <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M10.05 4.575a1.575 1.575 0 1 0-3.15 0v3m3.15-3v-1.5a1.575 1.575 0 0 1 3.15 0v1.5m-3.15 0 .075 5.925m3.075.75V4.575m0 0a1.575 1.575 0 0 1 3.15 0V15M6.9 7.575a1.575 1.575 0 1 0-3.15 0v8.175a6.75 6.75 0 0 0 6.75 6.75h2.018a5.25 5.25 0 0 0 3.712-1.538l1.732-1.732a5.25 5.25 0 0 0 1.538-3.712l.003-2.024a.668.668 0 0 1 .198-.471 1.575 1.575 0 1 0-2.228-2.228 3.818 3.818 0 0 0-1.12 2.687M6.9 7.575V12m6.27 4.318A4.49 4.49 0 0 1 16.35 15m.002 0h-.002" />
      </svg>,
    'microchip-ai': <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M8.25 3v1.5M4.5 8.25H3m18 0h-1.5M4.5 12H3m18 0h-1.5m-15 3.75H3m18 0h-1.5M8.25 19.5V21M12 3v1.5m0 15V21m3.75-18v1.5m0 15V21m-9-1.5h10.5a2.25 2.25 0 0 0 2.25-2.25V6.75a2.25 2.25 0 0 0-2.25-2.25H6.75A2.25 2.25 0 0 0 4.5 6.75v10.5a2.25 2.25 0 0 0 2.25 2.25Zm.75-12h9v9h-9v-9Z" />
      </svg>,
    'shield-check': <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M9 12.75 11.25 15 15 9.75m-3-7.036A11.959 11.959 0 0 1 3.598 6 11.99 11.99 0 0 0 3 9.749c0 5.592 3.824 10.29 9 11.623 5.176-1.332 9-6.03 9-11.622 0-1.31-.21-2.571-.598-3.751h-.152c-3.196 0-6.1-1.248-8.25-3.285Z" />
      </svg>,
    chain: <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M13.19 8.688a4.5 4.5 0 0 1 1.242 7.244l-4.5 4.5a4.5 4.5 0 0 1-6.364-6.364l1.757-1.757m13.35-.622 1.757-1.757a4.5 4.5 0 0 0-6.364-6.364l-4.5 4.5a4.5 4.5 0 0 0 1.242 7.244" />
      </svg>,
    leaf: <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0 3.181 3.183a8.25 8.25 0 0 0 13.803-3.7M4.031 9.865a8.25 8.25 0 0 1 13.803-3.7l3.181 3.182m0-4.991v4.99" />
      </svg>,
    'chart-line': <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M3.75 3v11.25A2.25 2.25 0 0 0 6 16.5h2.25M3.75 3h-1.5m1.5 0h16.5m0 0h1.5m-1.5 0v11.25A2.25 2.25 0 0 1 18 16.5h-2.25m-7.5 0h7.5m-7.5 0-1 3m8.5-3 1 3m0 0 .5 1.5m-.5-1.5h-9.5m0 0-.5 1.5M9 11.25v1.5M12 9v3.75m3-6v6" />
      </svg>,
    code: <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M17.25 6.75 22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3-4.5 16.5" />
      </svg>,
    headset: <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M2.25 6.75c0 8.284 6.716 15 15 15h2.25a2.25 2.25 0 0 0 2.25-2.25v-1.372c0-.516-.351-.966-.852-1.091l-4.423-1.106c-.44-.11-.902.055-1.173.417l-.97 1.293c-.282.376-.769.542-1.21.38a12.035 12.035 0 0 1-7.143-7.143c-.162-.441.004-.928.38-1.21l1.293-.97c.363-.271.527-.734.417-1.173L6.963 3.102a1.125 1.125 0 0 0-1.091-.852H4.5A2.25 2.25 0 0 0 2.25 4.5v2.25Z" />
      </svg>,
    filter: <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M12 3c2.755 0 5.455.232 8.083.678.533.09.917.556.917 1.096v1.044a2.25 2.25 0 0 1-.659 1.591l-5.432 5.432a2.25 2.25 0 0 0-.659 1.591v2.927a2.25 2.25 0 0 1-1.244 2.013L9.75 21v-6.568a2.25 2.25 0 0 0-.659-1.591L3.659 7.409A2.25 2.25 0 0 1 3 5.818V4.774c0-.54.384-1.006.917-1.096A48.32 48.32 0 0 1 12 3Z" />
      </svg>,
    'layer-group': <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M6 6.878V6a2.25 2.25 0 0 1 2.25-2.25h7.5A2.25 2.25 0 0 1 18 6v.878m-12 0c.235-.083.487-.128.75-.128h10.5c.263 0 .515.045.75.128m-12 0A2.25 2.25 0 0 0 4.5 9v.878m13.5-3A2.25 2.25 0 0 1 19.5 9v.878m0 0a2.246 2.246 0 0 0-.75-.128H5.25c-.263 0-.515.045-.75.128m15 0A2.25 2.25 0 0 1 21 12v6a2.25 2.25 0 0 1-2.25 2.25H5.25A2.25 2.25 0 0 1 3 18v-6c0-.98.626-1.813 1.5-2.122" />
      </svg>,
    bookmark: <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M17.593 3.322c1.1.128 1.907 1.077 1.907 2.185V21L12 17.25 4.5 21V5.507c0-1.108.806-2.057 1.907-2.185a48.507 48.507 0 0 1 11.186 0Z" />
      </svg>,
    'share-nodes': <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M9 8.25H7.5a2.25 2.25 0 0 0-2.25 2.25v9a2.25 2.25 0 0 0 2.25 2.25h9a2.25 2.25 0 0 0 2.25-2.25v-9a2.25 2.25 0 0 0-2.25-2.25H15m0-3-3-3m0 0-3 3m3-3V15" />
      </svg>,
    'file-export': <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5M16.5 12 12 16.5m0 0L7.5 12m4.5 4.5V3" />
      </svg>,
    'wand-magic-sparkles': <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M9.813 15.904 9 18.75l-.813-2.846a4.5 4.5 0 0 0-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 0 0 3.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 0 0 3.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 0 0-3.09 3.09ZM18.259 8.715 18 9.75l-.259-1.035a3.375 3.375 0 0 0-2.455-2.456L14.25 6l1.036-.259a3.375 3.375 0 0 0 2.455-2.456L18 2.25l.259 1.035a3.375 3.375 0 0 0 2.456 2.456L21.75 6l-1.035.259a3.375 3.375 0 0 0-2.456 2.456ZM16.894 20.567 16.5 21.75l-.394-1.183a2.25 2.25 0 0 0-1.423-1.423L13.5 18.75l1.183-.394a2.25 2.25 0 0 0 1.423-1.423l.394-1.183.394 1.183a2.25 2.25 0 0 0 1.423 1.423l1.183.394-1.183.394a2.25 2.25 0 0 0-1.423 1.423Z" />
      </svg>,
    'circle-question': <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M9.879 7.519c1.171-1.025 3.071-1.025 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45 1.827v.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 5.25h.008v.008H12v-.008Z" />
      </svg>,
    stairs: <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M2.25 18 9 11.25l4.306 4.306a11.95 11.95 0 0 1 5.814-5.518l2.74-1.22m0 0-5.94-2.281m5.94 2.28-2.28 5.941" />
      </svg>,
    'arrow-right': <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M13.5 4.5 21 12m0 0-7.5 7.5M21 12H3" />
      </svg>,
    python: <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M14.25 9.75 16.5 12l-2.25 2.25m-4.5 0L7.5 12l2.25-2.25M6 20.25h12A2.25 2.25 0 0 0 20.25 18V6A2.25 2.25 0 0 0 18 3.75H6A2.25 2.25 0 0 0 3.75 6v12A2.25 2.25 0 0 0 6 20.25Z" />
      </svg>,
    'code-branch': <svg width="20" height="20" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5">
        <path strokeLinecap="round" strokeLinejoin="round" d="M17.25 6.75 22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3-4.5 16.5" />
      </svg>
  };
  const resolvedIcon = typeof icon === 'string' ? icons[icon] : icon;
  const Tag = href ? 'a' : 'div';
  const linkProps = href ? {
    href
  } : {};
  return <Tag {...linkProps} className="rb-card">
      <span className="rb-ch rb-ch--tl" />
      <span className="rb-ch rb-ch--tr" />
      <span className="rb-ch rb-ch--bl" />
      <span className="rb-ch rb-ch--br" />
      <div className="rb-card-header">
        {resolvedIcon && <div className="rb-card-icon">{resolvedIcon}</div>}
        <div className="rb-card-name">{title}</div>
      </div>
      {desc && <p className="rb-card-desc">{desc}</p>}
      {children && <div className={stat ? 'rb-card-stat' : 'rb-card-desc'}>{children}</div>}
      {tag && <span className="rb-card-tag">{tag}</span>}
    </Tag>;
};

<Note>
  The [Data Dictionary](/docs/data-features/data-dictionary#per_latest) has the most up-to-date field definitions for all RevenueBase tables. Use it as your primary reference for column names and descriptions.
</Note>

The `historical_experience` table tracks career history for contacts in the RevenueBase database. Each row represents one LinkedIn profile with a nested array structure: a `jobs` array containing job objects, each with an `experience` array of position records. Use it to understand career trajectories, identify recent job changers, find alumni of specific organizations, and build more personalized outreach.

## Where the data comes from

Historical experience is derived from professional profiles and public career history. Positions are normalized to titles, seniority, and department where possible. Start and end dates are captured with the precision available from the source (sometimes year-only for older roles). Tenure is calculated from those dates.

## Counts and coverage

Each row represents one LinkedIn profile with nested arrays: a `jobs` array containing job objects, each with an `experience` array of position records. Not every contact has historical experience; fill rates are higher for recent roles and for people with detailed public profiles. Use the fill-rate query below to see coverage and average positions per profile.

## Table stats

| Metric                | Value                                                                                   |
| --------------------- | --------------------------------------------------------------------------------------- |
| **Total records**     | One row per LinkedIn profile (with array of jobs)                                       |
| **Update frequency**  | Monthly (aligned with contacts release)                                                 |
| **Primary key**       | `linkedin_url`                                                                          |
| **Main foreign keys** | Join to `PER_LATEST` table on `linkedin_url`, join to `ORG_LATEST` table via `rbid_org` |

## Data dictionary

For the complete and most current field reference, see the [Data Dictionary](/docs/data-features/data-dictionary).

Fill rates for historical data are typically lower than for current-position data. Older positions, smaller organizations, and non-US contacts tend to have less complete records. The table structure uses one row per LinkedIn profile with an array of job positions.

### Top-level fields

| Field          | Type    | Description                                     |
| -------------- | ------- | ----------------------------------------------- |
| `unique_id`    | VARCHAR | Unique identifier for this record               |
| `linkedin_url` | VARCHAR | LinkedIn profile URL (primary key)              |
| `job_count`    | INTEGER | Maximum number of jobs for this profile         |
| `jobs`         | ARRAY   | Array of job objects containing experience data |

### Jobs array structure

Each element in the `jobs` array is an object containing:

| Field           | Type    | Description                                             |
| --------------- | ------- | ------------------------------------------------------- |
| `rbid`          | VARCHAR | RevenueBase person identifier (from `PER_LATEST` table) |
| `rbid_pao`      | VARCHAR | RevenueBase person-at-organization identifier           |
| `rbid_org`      | VARCHAR | RevenueBase organization identifier                     |
| `linkedin_id`   | INTEGER | LinkedIn organization page ID (from `ORG_LATEST` table) |
| `email_address` | VARCHAR | Email address (from `PER_LATEST` table)                 |
| `experience`    | ARRAY   | Array of experience objects containing position details |

### Experience array structure

Each element in the `experience` array within a job object contains:

| Field                  | Type    | Description                                   |
| ---------------------- | ------- | --------------------------------------------- |
| `job_title`            | VARCHAR | Job title for this position                   |
| `job_org_name`         | VARCHAR | Organization name for this position           |
| `job_org_linkedin_url` | VARCHAR | LinkedIn organization page URL                |
| `job_function`         | VARCHAR | Department or functional area                 |
| `job_is_current`       | BOOLEAN | Whether this is the person's current position |

<Info>**One row per LinkedIn profile with nested arrays.** Each row contains a `jobs` array. Each job object contains an `experience` array with one or more position records. A person may have multiple positions at the same organization (different roles over time), which is why `experience` is an array. Use nested array functions to query and filter individual positions.</Info>

<Note>The `experience` array structure may include additional fields like `start_date`, `end_date`, and other position-related attributes depending on data availability. Query the nested arrays to access individual job positions.</Note>

### Joining to other tables

The `jobs` array contains `rbid`, `rbid_org`, and `email_address` that you can use to join to other tables. The `experience` array within each job contains position-specific details:

| Approach                       | When to use                                                                                                                                         |
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Join to person table**       | Use `jobs[].rbid` or join on `linkedin_url` to get current contact information                                                                      |
| **Join to organization table** | Use `jobs[].rbid_org` to get organization firmographics and HQ address for that employer                                                            |
| **Access position details**    | Flatten both `jobs` and `experience` arrays to access individual position fields like `job_title`, `job_org_name`, `job_function`, `job_is_current` |
| **Contact's current location** | For "where does this person live now," use **contacts** (`CITY`, `STATE_NAME`, `COUNTRY_NAME`), not historical experience                           |

<Tip>To analyze "contacts who worked in California" or "alumni of organizations in EMEA," flatten both the `jobs` and `experience` arrays, join to `org_latest` on `rbid_org`, and filter on organization location fields.</Tip>

<Warning>**Fill rates for historical data are inherently lower** than for current-position data. Older positions, smaller organizations, and non-US contacts tend to have less complete records. The `experience` object may not contain all fields for every position, and `rbid_org` may be null when the employer is not in the RevenueBase organizations table.</Warning>

## Common use cases

<AccordionGroup>
  <Accordion title="Find recent job changers">
    People who just started a new role are often more receptive to new tools. Flatten both the `jobs` and `experience` arrays and filter for positions where `experience.job_is_current = TRUE`. Join to the person table and filter by `UPDATED_AT` to find recently updated profiles.
  </Accordion>

  <Accordion title="Organization alumni targeting">
    Find everyone who used to work at a specific organization by flattening both arrays and filtering for `experience.job_org_linkedin_url` matching the target organization, or use `jobs[].rbid_org` to join to the organization table. Filter for `experience.job_is_current = FALSE`. Useful for selling to former champions who already know your space.
  </Accordion>

  <Accordion title="Career trajectory analysis">
    Flatten both arrays and compare `job_title`, `job_function`, and `job_org_name` across positions for a profile. Use `job_count` to identify profiles with multiple positions, then analyze the progression in the nested arrays.
  </Accordion>

  <Accordion title="Multiple positions at same organization">
    Some profiles may have multiple entries in the `experience` array within the same job object, representing different roles at the same organization over time. Flatten both arrays to see all positions and their progression.
  </Accordion>
</AccordionGroup>

## Joining this table

Join `HISTORICAL_EXPERIENCE_LATEST` to `PER_LATEST` table on `linkedin_url` to get current contact info. Flatten both the `jobs` and `experience` arrays to access individual positions. Join to `org_latest` table using `jobs[].rbid_org` when you need firmographics or HQ address for a specific role.

### Flattening the nested arrays

To work with individual positions, you need to flatten both the `jobs` array and the `experience` array within each job. Here's a pattern for Snowflake:

```sql theme={null}
SELECT
    he.linkedin_url,
    he.unique_id,
    job.value:rbid AS rbid,
    job.value:rbid_org AS rbid_org,
    job.value:rbid_pao AS rbid_pao,
    job.value:email_address AS email_address,
    job.value:linkedin_id AS linkedin_id,
    exp.value:job_title AS job_title,
    exp.value:job_org_name AS job_org_name,
    exp.value:job_org_linkedin_url AS job_org_linkedin_url,
    exp.value:job_function AS job_function,
    exp.value:job_is_current AS job_is_current
FROM RELEASE.HISTORICAL_EXPERIENCE_LATEST he,
LATERAL FLATTEN(input => he.jobs) job,
LATERAL FLATTEN(input => job.value:experience) exp
WHERE exp.value IS NOT NULL;
```

### Historical experience + contacts (recent job changers with contact info)

```sql theme={null}
SELECT
    per.FIRST_NAME,
    per.LAST_NAME,
    per.EMAIL_ADDRESS,
    exp.value:job_title AS new_title,
    exp.value:job_org_name AS new_company,
    per.JOB_TITLE AS current_title_in_feed
FROM RELEASE.HISTORICAL_EXPERIENCE_LATEST he
JOIN RELEASE.PER_LATEST per ON he.linkedin_url = per.LINKEDIN_URL
, LATERAL FLATTEN(input => he.jobs) job
, LATERAL FLATTEN(input => job.value:experience) exp
WHERE exp.value:job_is_current = TRUE
  AND per.EMAIL_ADDRESS IS NOT NULL
ORDER BY per.UPDATED_AT DESC;
```

### Historical experience + contacts + organizations (alumni with HQ location)

```sql theme={null}
SELECT
    per.FIRST_NAME,
    per.LAST_NAME,
    per.EMAIL_ADDRESS,
    exp.value:job_org_name AS former_employer,
    exp.value:job_title AS former_title,
    org.HEADQUARTERS_COUNTRY_NAME_ORG,
    org.HEADQUARTERS_CITY_ORG
FROM RELEASE.HISTORICAL_EXPERIENCE_LATEST he
JOIN RELEASE.PER_LATEST per ON he.linkedin_url = per.LINKEDIN_URL
, LATERAL FLATTEN(input => he.jobs) job
, LATERAL FLATTEN(input => job.value:experience) exp
LEFT JOIN RELEASE.ORG_LATEST org ON job.value:rbid_org = org.RBID
WHERE exp.value:job_org_linkedin_url LIKE '%salesforce%'
  AND exp.value:job_is_current = FALSE
  AND per.EMAIL_ADDRESS IS NOT NULL
ORDER BY per.UPDATED_AT DESC;
```

## How to calculate fill rates

Use this to see how many profiles you have, how many positions total, and how complete key fields are.

```sql theme={null}
SELECT
    COUNT(*) AS total_profiles,
    SUM(job_count) AS total_positions,
    ROUND(AVG(job_count), 1) AS avg_positions_per_profile,
    COUNT(DISTINCT linkedin_url) AS unique_profiles
FROM RELEASE.HISTORICAL_EXPERIENCE_LATEST;

-- To analyze individual positions, flatten both arrays:
SELECT
    COUNT(*) AS total_positions,
    ROUND(COUNT(job.value:rbid_org) * 100.0 / COUNT(*), 1) AS rbid_org_fill_pct,
    ROUND(COUNT(exp.value:job_title) * 100.0 / COUNT(*), 1) AS job_title_fill_pct,
    ROUND(COUNT(exp.value:job_org_name) * 100.0 / COUNT(*), 1) AS job_org_name_fill_pct,
    ROUND(COUNT(exp.value:job_function) * 100.0 / COUNT(*), 1) AS job_function_fill_pct
FROM RELEASE.HISTORICAL_EXPERIENCE_LATEST he,
LATERAL FLATTEN(input => he.jobs) job,
LATERAL FLATTEN(input => job.value:experience) exp
WHERE exp.value IS NOT NULL;
```

## Sample queries

### Recent job changers (last 90 days)

**What you're finding:** People who started a new job in the last 90 days, for outreach or lead scoring.

**Why these fields:** We need current contact info from the person table and the new role from the flattened jobs array. Filter for current positions with recent start dates.

**Logic:** Flatten both the jobs and experience arrays, filter to current positions (`job_is_current = TRUE`). Join to person table for contact info. Use `UPDATED_AT` to identify recently updated profiles.

```sql theme={null}
SELECT
    per.FIRST_NAME,
    per.LAST_NAME,
    per.EMAIL_ADDRESS,
    exp.value:job_title AS new_title,
    exp.value:job_org_name AS new_company,
    per.UPDATED_AT AS profile_updated_at
FROM RELEASE.HISTORICAL_EXPERIENCE_LATEST he
JOIN RELEASE.PER_LATEST per ON he.linkedin_url = per.LINKEDIN_URL
, LATERAL FLATTEN(input => he.jobs) job
, LATERAL FLATTEN(input => job.value:experience) exp
WHERE exp.value:job_is_current = TRUE
  AND per.UPDATED_AT >= DATEADD(day, -90, CURRENT_DATE())
  AND per.EMAIL_ADDRESS IS NOT NULL
ORDER BY per.UPDATED_AT DESC;
```

### Alumni of a specific organization

**What you're finding:** People who used to work at a given organization (e.g. Salesforce), with current contact info, for alumni campaigns or competitive targeting.

**Why these fields:** Filter the jobs array for the target organization's domain and non-current positions. Join to person table for current contact info.

**Logic:** Flatten both arrays, filter by target organization LinkedIn URL pattern and non-current positions. Join to person table for email and current context. Order by profile update date descending.

```sql theme={null}
SELECT
    per.FIRST_NAME,
    per.LAST_NAME,
    per.EMAIL_ADDRESS,
    per.JOB_TITLE AS current_title,
    per.COMPANY_NAME AS current_company,
    exp.value:job_title AS former_title,
    exp.value:job_org_name AS former_employer,
    exp.value:job_org_linkedin_url AS former_company_linkedin
FROM RELEASE.HISTORICAL_EXPERIENCE_LATEST he
JOIN RELEASE.PER_LATEST per ON he.linkedin_url = per.LINKEDIN_URL
, LATERAL FLATTEN(input => he.jobs) job
, LATERAL FLATTEN(input => job.value:experience) exp
WHERE exp.value:job_org_linkedin_url LIKE '%salesforce%'
  AND exp.value:job_is_current = FALSE
  AND per.EMAIL_ADDRESS IS NOT NULL
ORDER BY per.UPDATED_AT DESC;
```

## Related

<RBCardGroup cols={2}>
  <RBCard title="Person" icon="user" href="/docs/data-features/data-tables/person" desc="Full field reference for person-level records, including current job title and contact info." />

  <RBCard title="Organization" icon="building" href="/docs/data-features/data-tables/organization" desc="Organization firmographics — headcount, industry, location, and tech stack." />

  <RBCard title="Joining Tables" icon="link" href="/docs/data-feeds/joining-overview" desc="How to join Historical Experience to Person and Organization using RBID keys." />

  <RBCard title="Data Freshness & Quality" icon="shield-check" href="/docs/data-features/data-freshness/data-freshness" desc="How records are verified and when historical data may be incomplete." />
</RBCardGroup>

### Profiles with multiple positions

**What you're finding:** Profiles that have held multiple positions, useful for career trajectory analysis.

**Why these fields:** Use `job_count` to identify profiles with multiple positions, then flatten to see all positions.

**Logic:** Filter for profiles with `job_count > 1`, then flatten both arrays to see all positions.

```sql theme={null}
SELECT
    he.linkedin_url,
    he.job_count,
    per.FIRST_NAME,
    per.LAST_NAME,
    exp.value:job_title AS job_title,
    exp.value:job_org_name AS company_name,
    exp.value:job_function AS job_function,
    exp.value:job_is_current AS is_current
FROM RELEASE.HISTORICAL_EXPERIENCE_LATEST he
JOIN RELEASE.PER_LATEST per ON he.linkedin_url = per.LINKEDIN_URL
, LATERAL FLATTEN(input => he.jobs) job
, LATERAL FLATTEN(input => job.value:experience) exp
WHERE he.job_count > 1
  AND exp.value IS NOT NULL
ORDER BY he.linkedin_url, exp.value:job_is_current DESC;
```
