Skip to content

API & MCPPartner Card

Partner Card

Add Robinhood Chain builder intelligence to your product in one call. Your product already shows the market. One call adds the other half: whether anyone is building the project behind a token, what they last shipped, and a link to the evidence. No key needed, no provider call on HEY’s side, and nothing in it is a buy or sell signal.

Try it on your token

Lockra Protocol, read from HEY’s database as this page loaded — the same answer your call gets. An example chosen by its most recent counted ship, not a recommendation.

Builder intelligence · Powered by HEY

Lockra Protocol

ShippingVerified Builder

Shipped something meaningful in the last 7 days.

Latest ship
Code changes, week starting 2026-11-09 (to 2026-11-14) · 35m ago
30 days
2 meaningful ships
Changed
The latest ship
Token
Named by the project
Market
Launch pool only · read 14m ago

Evidence →Research on HEY →

Scored 9m ago. Not a rating and not a price signal.

The JSON behind it · read 2026-11-14 15:22 UTC
{
  "contract_address": "0x2fc6de9c65a620f918ca7d1191d3afa495ca2898",
  "chain_id": 4663,
  "last_activity_at": "2026-11-14T14:47:01.000Z",
  "status": "active",
  "token_verification": "VERIFIED",
  "activity_applies_to_token": true,
  "hey_project_url": "https://heyresearch.xyz/project/lockra-protocol",
  "repo_url": "https://github.com/LockraProtocol/lockra-dev",
  "last_commit": null,
  "last_code_activity": {
    "summary": "Code changes, week starting 2026-11-09 (to 2026-11-14)",
    "commits": 42,
    "commits_partial": false,
    "commits_30d": 29,
    "window_start": "2026-10-15T15:22:52.745Z",
    "active_days": 3,
    "contributors": 1,
    "repo_url": "https://github.com/lockraprotocol/lockra-dev",
    "observed_at": "2026-11-14T14:47:01.000Z"
  },
  "latest_release": {
    "title": "v1.0.2",
    "version": "v1.0.2",
    "url": "https://github.com/LockraProtocol/lockra-dev/releases/tag/v1.0.2",
    "timestamp": "2026-11-12T13:27:38.000Z"
  },
  "latest_deployment": null,
  "research_level": "VERIFIED_BUILDER",
  "activity_measured": true,
  "as_of": "2026-11-14T15:13:52.116Z",
  "verified_builder": true,
  "latest_meaningful_ship": {
    "title": "Code changes, week starting 2026-11-09 (to 2026-11-14)",
    "url": "https://github.com/lockraprotocol/lockra-dev",
    "timestamp": "2026-11-14T14:47:01.000Z",
    "kind": "CODE_ACTIVITY",
    "evidence_id": "ship:53f0111a-a870-4a12-9162-843f19736542",
    "evidence_link": "https://heyresearch.xyz/evidence/ship:53f0111a-a870-4a12-9162-843f19736542?utm_source=hey_api&utm_medium=partner_api&utm_campaign=builder_card"
  },
  "meaningful_ships_30d": 2,
  "latest_change": {
    "id": "ship:53f0111a-a870-4a12-9162-843f19736542",
    "type": "build.code_activity",
    "summary": "Code changes, week starting 2026-11-09 (to 2026-11-14)",
    "occurred_at": "2026-11-14T14:47:01.000Z",
    "precision": "WEEK",
    "detected_at": "2026-11-12T21:51:51.685Z",
    "evidence_id": "ship:53f0111a-a870-4a12-9162-843f19736542",
    "url": "https://heyresearch.xyz/api/evidence/ship%3A53f0111a-a870-4a12-9162-843f19736542",
    "explanation": {
      "version": "change-explain-v1",
      "headline": "Code changes, read from the team’s GitHub · not a deployment",
      "stage": "code",
      "reported_by": "team_source",
      "corroboration": "not_corroborated",
      "release_deployment": "not_applicable",
      "activity": "NOT_APPLICABLE",
      "call_success": "not_measured",
      "time_basis": "source_dated",
      "standing": "standing",
      "unknowns": [
        "capability_not_named",
        "deployment_not_observed"
      ],
      "explain_url": "https://heyresearch.xyz/api/projects/lockra-protocol/explain?fact=build.change&event=ship%3A53f0111a-a870-4a12-9162-843f19736542"
    }
  },
  "latest_change_state": "recorded",
  "latest_signal": {
    "id": "9585ab18-4d7a-4f85-9a70-024b5c4f2615",
    "kind": "builder_verified",
    "label": "Became a Verified Builder",
    "headline": "Verified Builder",
    "observed_at": "2026-11-12T22:13:46.537Z",
    "evidence_id": "signal:9585ab18-4d7a-4f85-9a70-024b5c4f2615",
    "url": "https://heyresearch.xyz/signals/9585ab18-4d7a-4f85-9a70-024b5c4f2615"
  },
  "market_status": {
    "status": "ACTIVE_MARKET",
    "observed_at": "2026-11-14T15:08:25.332Z",
    "reason": "launch_pool_trading",
    "label": "Launch pool only"
  },
  "badge_url": "https://heyresearch.xyz/badge/lockra-protocol.svg",
  "project_link": "https://heyresearch.xyz/project/lockra-protocol?utm_source=hey_api&utm_medium=partner_api&utm_campaign=builder_card",
  "uniswap_v4_hooks": null,
  "uniswap_v4_hooks_state": "none_listed",
  "hey_status": "SHIPPING",
  "hey_status_label": "Shipping",
  "hey_status_help": "Shipped something meaningful in the last 7 days.",
  "hey_project_name": "Lockra Protocol",
  "disclaimer": "HEY reports what a team shipped and how it knows. It is not a rating, not a verdict, and says nothing about what a token will do."
}

See this card inside a token card, beside five real cases →

The call

GET /api/v1/builder?chain=4663&token=0x…

Auth
None; a free key names you and unlocks bulk; holder and partner keys lift limits
Cache · CORS
60 seconds · open

One question, three reads

Start from the Partner Card. The other two are older shapes of the same answer, kept as they are for the bots that read them. All three print the same status words; they differ only here.

  • /api/v1/builder — The Partner Card. Start here.
  • /api/v1/scan — The Chit card: a one-line bot card.
  • /api/token/{chainId}/{address} — A chat line, with a bulk form.

HEY has not published the token

/api/v1/builder
404 not_found with scan_url
/api/v1/scan
200 found: false with scan_url
/api/token/{chainId}/{address}
200 status: "unknown" with scanUrl

A chain HEY does not index

/api/v1/builder
400 bad_request
/api/v1/scan
200 found: false, reason: "chain"
/api/token/{chainId}/{address}
400 bad_request

Building not measured

/api/v1/builder
activity_measured: false; meaningful_ships_30d is null
/api/v1/scan
activity_measured: false; meaningful_ships_30d absent; ships_30d and releases_30d read 0 (legacy)
/api/token/{chainId}/{address}
activityMeasured: false; meaningfulShipsLast30Days absent; shipsLast30Days reads 0 (legacy)

Live in fifteen minutes

Three steps, each one copyable, each one runs against HEY as printed. The contract is the card above; put your own token in its place.

The snippets send a placeholder HEY never counts. Type your product’s name and every snippet below uses it; nothing you type leaves this page.

  1. 1. Make the call · about 2 min

    No key, no sign-up. A 200 is the card; a 404 means HEY has not published a project for that contract.

    curl -H "x-hey-integration: my-product/1.0.0" \
      "https://heyresearch.xyz/api/v1/builder?chain=4663&token=0x2fc6de9c65a620f918ca7d1191d3afa495ca2898"
  2. 2. Read it in TypeScript · about 5 min

    The typed client: no dependencies, Node 18+ or any runtime with fetch. The card’s type is HeyBuilderCard.

    npm install @hey-research-lab/sdk
    import { HeyClient } from '@hey-research-lab/sdk';
    
    // Names your integration on every call (x-hey-integration), so HEY can tell you what it sent back.
    const hey = new HeyClient({ integration: 'my-product/1.0.0' });
    
    // One builder line for a token card, or null to print nothing.
    export async function heyBuilderLine(token: string) {
      try {
        const card = await hey.builderCard(4663, token);
        if (!card.activity_applies_to_token) {
          // The project's own site names another contract: never print its activity as this token's.
          return { text: card.hey_project_name + ': the research is about the project, not this token', href: card.project_link };
        }
        const ship = card.latest_meaningful_ship;
        return {
          status: card.hey_status_label, // HEY's words, never your own
          verified: card.verified_builder,
          latestShip: ship ? { title: ship.title, at: ship.timestamp, evidence: ship.evidence_id } : null,
          ships30d: card.meaningful_ships_30d, // null = not measured: print nothing, never 0
          href: card.project_link, // the one condition of use
        };
      } catch {
        return null; // 404 not published · 400 not a token · 429 or 5xx: stay quiet
      }
    }
  3. 3. Render it beside your chart · about 8 min

    For a React token card or terminal: one fetch, CORS open, nothing rendered as HTML, and nothing at all when HEY has no answer.

    import { useEffect, useState } from 'react';
    
    const HEY = 'https://heyresearch.xyz';
    
    type HeyCard = {
      hey_project_name: string;
      hey_status_label: string;
      verified_builder: boolean;
      activity_applies_to_token: boolean;
      meaningful_ships_30d: number | null;
      latest_meaningful_ship: { title: string; timestamp: string } | null;
      project_link: string;
    };
    
    export function HeyBuilderPanel({ token }: { token: string }) {
      const [card, setCard] = useState<HeyCard | null>(null);
      useEffect(() => {
        let live = true;
        fetch(HEY + '/api/v1/builder?chain=4663&integration=my-terminal&token=' + encodeURIComponent(token))
          .then((r) => (r.ok ? r.json() : null))
          .then((c) => live && setCard(c))
          .catch(() => live && setCard(null));
        return () => { live = false; };
      }, [token]);
    
      if (!card) return null; // not published, not a token, or a failure: print nothing
      const own = card.activity_applies_to_token;
      const ship = card.latest_meaningful_ship;
      return (
        <aside>
          <strong>{card.hey_project_name}</strong>
          {own ? <p>Builder: {card.hey_status_label}{card.verified_builder ? ' · Verified Builder' : ''}</p> : <p>The project names another contract.</p>}
          {own && ship ? <p>Latest: {ship.title} · {new Date(ship.timestamp).toLocaleDateString()}</p> : null}
          {own && card.meaningful_ships_30d !== null ? <p>{card.meaningful_ships_30d} meaningful ships in 30 days</p> : null}
          <a href={card.project_link} target="_blank" rel="noopener">Evidence on HEY</a>
        </aside>
      );
    }

Every fact opens its receipt

  • Typed ids. A ship carries evidence_id as ship:<uuid>, a signal as signal:<uuid>; latest_change.evidence_id is the first evidence behind the change. Never a bare table key, never a slug.
  • One call resolves any of them. GET /api/evidence/{id}, no key, returns the record’s source, its dates and their precision, and how HEY verified it. latest_change.url is that call, already built, and latest_meaningful_ship.evidence_link is the receipt page a reader can open.
  • Withdrawn is said, not hidden. When HEY stops standing behind a record, the receipt says so and why, and the card’s counts stop including it. Cache a card for minutes, not days.
  • Dates are what they say. occurred_at is set only when the source dated the event; detected_at is when HEY saw it, and precision says which one you have.

Six things to get right

  • Carry the link. Whatever you render, link project_link. Someone who sees a HEY line should be one tap from the evidence behind it. This is the one condition of use.
  • Print HEY’s words. Use hey_status_label, never your own word for the status. There is no “abandoned”, “dead” or “risky” in HEY’s vocabulary, and a quiet project is not a failed one. For a count of building, print meaningful_ships_30d — never the scan card’s releases_30d, which counts every tag a repository cut.
  • Unknown is not zero. A null count means HEY did not measure it. Print nothing, or “not measured”, never “0 ships”. activity_measured: false means an unknown status is not a finding.
  • A token is not a project. When activity_applies_to_token is false the project’s own site names another contract: never print the activity as this token’s, and do not link the token to the project.
  • No verdict, no signal. HEY sends no score, no grade and no safe or unsafe reading, and building says nothing about what a token will do. Put a risk read from a tool that does that work beside the line, not inside it.
  • Stay quiet on a failure. A 404 means HEY has not published a project for that contract (offer scan_url); a 400 is a malformed address; on 429 or 5xx print nothing rather than a guess.

Eight facts, each one HEY can back

Every partner card can show these. Anything HEY does not hold is an explicit null or a stated state, never a zero.

  • Builder status

    hey_status_label, hey_status, status, activity_measured

    Print hey_status_label: the project page’s own words, which already say why an unmeasured status is unknown (“Not measured — no builder source linked”). When activity_measured is false, render it muted — never as a finding.

  • Verified Builder

    verified_builder

    Show “Verified Builder” when true; show nothing when false.

  • Latest meaningful ship

    latest_meaningful_ship

    title · relative time of timestamp; link evidence_link as “Evidence”. Nothing when null.

  • Ships / 30d

    meaningful_ships_30d

    “N meaningful ships / 30d”. When null, print nothing — never “0 ships”.

  • Latest change

    latest_change, latest_change_state

    summary · relative time of occurred_at (else detected_at, “observed”); link url. When unavailable, print nothing.

  • Project URL

    project_link, hey_project_url

    Always link project_link: the one condition of use.

  • Badge

    badge_url

    An SVG image; optional.

  • Freshness

    as_of, last_activity_at

    “Scored <relative as_of>”. Keep an answer 60 seconds at most; HEY answers every call fresh from its own database.

Every field, its type and its unknown
contract_address

string · since 2026-09-20

The contract asked about, lower-cased.
chain_id

integer · since 2026-09-20

The chain HEY indexes: Robinhood Chain, 4663.
status

string · since 2026-09-20

active, stale, dormant or unknown. There is no abandoned: HEY sees silence, not intent.Unknown: unknown: not enough public sources to say either way.
hey_status

string · since 2026-09-20

HEY’s own activity status: SHIPPING, ACTIVE, RESUMED, QUIET, DORMANT or UNKNOWN. Derived from what the project ships, never from price.
hey_status_label

string · since 2026-09-20

The status in HEY’s words — the project page’s chip, the scan card’s status_label and the token lookup’s activityLabel print the same (since 2026-10-18 an UNKNOWN says why where the page does; since 2026-10-28 under one head, “Not measured — no builder source linked”). Print this rather than a word of your own.
hey_status_help

string · since 2026-09-20

One sentence explaining the status.
hey_project_name

string · since 2026-09-26

The project’s name as HEY publishes it.
hey_project_url

string · since 2026-09-20

The canonical project page, without labels.
project_link

string · since 2026-09-30

The project page with HEY’s attribution labels (utm_medium=partner_api, utm_source = your declared integration or hey_api). Link this one.
token_verification

string · since 2026-09-25

VERIFIED, UNVERIFIED or MISMATCH: whether the project itself names this contract.
activity_applies_to_token

boolean · since 2026-09-27

False exactly on MISMATCH: then print the activity as the project’s, never as this token’s, and do not link the token to the project.
verified_builder

boolean · since 2026-09-30

HEY verified the project as a builder, source by source (the badge the project page shows).
research_level

string · since 2026-09-26

INDEXED, RESEARCHED or VERIFIED_BUILDER: how far HEY’s research went.
activity_measured

boolean · since 2026-09-26

Whether HEY measured this project’s building at all. False means an unknown status is not a finding.
last_activity_at

string | null · since 2026-09-20

The project’s most recent meaningful activity HEY recorded (ISO 8601).Unknown: null when HEY holds none.
latest_meaningful_ship

object | null · since 2026-09-30

The newest ship HEY counts as building evidence now: title, url, timestamp, kind, its ship: evidence id and evidence_link (since 2026-10-05: the reader’s receipt page with your attribution labels — link this as “Evidence”).Unknown: null when HEY holds none.
meaningful_ships_30d

integer | null · since 2026-09-30

Meaningful ships in thirty days by the rule behind the status: a week of prereleases or code summaries counts once.Unknown: null — never 0 — when HEY did not measure building and holds none.
latest_change

object | null · since 2026-09-30

The latest builder-side event in HEY’s change ledger, by the Research Summary’s rule (the project’s own change before HEY’s reclassifications; 2026-10-20): id, type, summary, occurred_at, precision, detected_at, evidence_id, url, and explanation (2026-10-20, additive: headline, stage, reported_by, corroboration, release_deployment — established only by an exact address in the release text, never by timing — activity, call_success always not_measured, time_basis, standing, unknowns, explain_url; null when HEY could not read it). Only the builder story: market, usage, lock, coverage and narrative events are left out.Unknown: null; latest_change_state says whether none was recorded or the ledger could not answer.
latest_change_state

string · since 2026-09-30

recorded, none_recorded or unavailable.Unknown: unavailable: the ledger has not run or could not be read — unknown, not none.
latest_signal

object | null · since 2026-09-30

The newest standing HEY Signal about building, contracts, launch or research, with its signal: evidence id. Market-group and address-count kinds are left out.Unknown: null when none stands.
repo_url

string | null · since 2026-09-20

A repository HEY counts as the project’s own evidence.Unknown: null when HEY counts none.
last_commit

null · since 2026-09-20

Always null: HEY aggregates commits into weekly summaries and stores no SHA. Read last_code_activity.
last_code_activity

object | null · since 2026-09-20

The newest weekly code summary, with commits_30d counted like the scan card’s. Its summary names a week still running as “week starting <Monday> (to <today>)”, never a range ending in days that have not happened (2026-10-16). Its commits and active_days are that week’s own counts, as the week’s receipt counts them (codeWeek.commits), never the read window behind it (2026-10-18); commits_partial says they are floors.Unknown: null when HEY holds none; commits and active_days null when HEY holds no count for the week.
latest_release

object | null · since 2026-09-20

The newest counted release: title, version, url, timestamp.Unknown: null when HEY holds none.
latest_deployment

object | null · since 2026-09-20

The newest counted post-launch deployment or upgrade. A launch itself is not a ship.Unknown: null when HEY holds none.
market_status

object · since 2026-09-30

This token’s market state (status, observed_at; since 2026-10-19 also reason, the classifier’s reason or null, and label, the status in HEY’s canonical words — “Launch pool only” for an active launch pool, “Readings not confirmed” for a depth reading over a week old; print label): context only, never a builder input and never a direction.Unknown: INSUFFICIENT_DATA with observed_at: null — not measured, not zero.
badge_url

string · since 2026-09-30

The project’s README badge (SVG).
uniswap_v4_hooks

object | null · since 2026-10-11

The project’s publicly listed Uniswap v4 hooks, under the rule HEY’s hook list applies: listed (every listed hook, factory instances included), basis_counts (chain, project, linked, factory, review: what each tie rests on), items (at most ten hooks with a row of their own, newest deployment first: address, basis, basis_label, page_url, the v4hook: evidence_id), shown of total, and list_url. Contracts and counts only: contract context, never a builder input or an order.Unknown: null; uniswap_v4_hooks_state says whether HEY lists none under the project or has decoded no hook on the chain.
uniswap_v4_hooks_state

string · since 2026-10-11

listed, none_listed or not_read. none_listed is a reading of HEY’s listing: a hook whose creation HEY has not read yet is tied to no project so far.Unknown: not_read: HEY has decoded no Uniswap v4 hook on the chain — unknown, not none.
as_of

string | null · since 2026-09-26

When HEY last scored the project: the moment the status and counts describe.Unknown: null when never scored.
disclaimer

string · since 2026-09-20

HEY reports what a team shipped and how it knows; not a rating, not a verdict.

Eight products, one call

Plain JavaScript you can paste. Each one is run by HEY’s test suite against the card’s real shape, so the code below is the code that was tested.

Telegram bot

A reply when someone pastes a contract into a chat, with one Evidence button.

const HEY = 'https://heyresearch.xyz';

// Returns a sendMessage payload, or null to stay quiet.
async function heyTelegramReply(token) {
  const r = await fetch(`${HEY}/api/v1/builder?chain=4663&token=${token}`, {
    headers: { 'x-hey-integration': 'my-telegram-bot/1.0.0' },
  });
  if (!r.ok) return null; // 404: HEY has no page · 400: not a token · 429/5xx: stay quiet
  const c = await r.json();

  const lines = [c.hey_project_name];
  if (!c.activity_applies_to_token) {
    lines.push("The project's own site names another contract. HEY's research is about the project, not this token.");
    return { text: lines.join('\n') };
  }
  lines.push('Builder: ' + c.hey_status_label + (c.verified_builder ? ' · Verified Builder' : ''));
  if (c.latest_meaningful_ship) lines.push('Latest: ' + c.latest_meaningful_ship.title + ' · ' + ago(c.latest_meaningful_ship.timestamp));
  if (c.meaningful_ships_30d !== null) lines.push('30d: ' + c.meaningful_ships_30d + ' meaningful ships');
  return {
    text: lines.join('\n'),
    reply_markup: { inline_keyboard: [[{ text: 'Evidence on HEY', url: c.project_link }]] },
  };
}

function ago(iso) {
  const h = Math.floor((Date.now() - Date.parse(iso)) / 3600000);
  return h < 24 ? h + 'h ago' : Math.floor(h / 24) + 'd ago';
}

Discord bot

An embed for a token lookup command.

const HEY = 'https://heyresearch.xyz';

// Returns a Discord embed, or null to stay quiet.
async function heyDiscordEmbed(token) {
  const r = await fetch(`${HEY}/api/v1/builder?chain=4663&token=${token}`, {
    headers: { 'x-hey-integration': 'my-discord-bot/1.0.0' },
  });
  if (!r.ok) return null;
  const c = await r.json();
  if (!c.activity_applies_to_token) return null; // the activity is the project's, not this token's

  const fields = [{ name: 'Builder', value: c.hey_status_label + (c.verified_builder ? ' · Verified Builder' : ''), inline: true }];
  if (c.meaningful_ships_30d !== null) fields.push({ name: 'Meaningful ships, 30d', value: String(c.meaningful_ships_30d), inline: true });
  if (c.latest_meaningful_ship) fields.push({ name: 'Latest ship', value: c.latest_meaningful_ship.title.slice(0, 200) });
  if (c.latest_change) fields.push({ name: 'Latest change', value: c.latest_change.summary.slice(0, 200) });
  return {
    title: c.hey_project_name,
    url: c.project_link,
    description: c.hey_status_help,
    fields,
    footer: { text: 'Builder intelligence by HEY Research Lab. Not a rating.' },
    timestamp: c.as_of ?? undefined,
  };
}

Trading terminal

A side panel beside the chart: the chart is the market, this is the builder.

const HEY = 'https://heyresearch.xyz';

// A side panel beside the chart: the builder half of the picture.
async function heyBuilderPanel(token) {
  const r = await fetch(`${HEY}/api/v1/builder?chain=4663&token=${token}`, {
    headers: { 'x-hey-integration': 'my-terminal/2.3.0' },
  });
  if (r.status === 404) return { state: 'not_indexed', href: (await r.json()).scan_url };
  if (!r.ok) return null;
  const c = await r.json();
  // The project names another contract: show none of its activity on this token.
  if (!c.activity_applies_to_token) return { state: 'other_contract' };
  return {
    state: 'ok',
    status: c.hey_status_label,           // HEY's word, never your own
    measured: c.activity_measured,        // false: "not measured yet", not "inactive"
    verified: c.verified_builder,
    latest: c.latest_meaningful_ship,     // null when HEY holds none; link its evidence_link as "Evidence"
    ships30d: c.meaningful_ships_30d,     // null is unknown, never render it as 0
    change: c.latest_change_state === 'recorded' ? c.latest_change : null,
    asOf: c.as_of,
    href: c.project_link,
  };
}

DEX interface

One row in a swap page’s token details.

const HEY = 'https://heyresearch.xyz';

// One row on a swap page's token details. Titles come from projects: escape them.
async function heyDexRow(token) {
  const r = await fetch(`${HEY}/api/v1/builder?chain=4663&token=${token}`, {
    headers: { 'x-hey-integration': 'my-dex/1.0.0' },
  });
  if (!r.ok) return '';
  const c = await r.json();
  if (!c.activity_applies_to_token) return '';
  const parts = [esc(c.hey_status_label)];
  if (c.meaningful_ships_30d !== null) parts.push(c.meaningful_ships_30d + ' ships / 30d');
  if (c.latest_meaningful_ship) parts.push('latest: ' + esc(c.latest_meaningful_ship.title));
  return '<div class="hey-row">Builder · ' + parts.join(' · ') +
    ' <a href="' + esc(c.project_link) + '" target="_blank" rel="noopener">Evidence ↗</a></div>';
}

function esc(s) {
  return String(s).replace(/[&<>"']/g, (ch) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' })[ch]);
}

Launchpad

Under a launch: whether HEY has found a builder behind it yet.

const HEY = 'https://heyresearch.xyz';

// Under a launch: whether HEY has found a builder behind it yet.
async function heyLaunchBadge(token) {
  const r = await fetch(`${HEY}/api/v1/builder?chain=4663&token=${token}`, {
    headers: { 'x-hey-integration': 'my-launchpad/1.0.0' },
  });
  if (r.status === 404) return { label: 'No HEY research yet', href: (await r.json()).scan_url, image: null };
  if (!r.ok) return null;
  const c = await r.json();
  if (!c.activity_applies_to_token) return null;
  return {
    label: c.verified_builder ? 'Verified Builder on HEY' : 'Researched on HEY: ' + c.hey_status_label,
    href: c.project_link,
    image: c.badge_url, // an SVG with the name, status and last ship
  };
}

Explorer

One line under a contract’s address.

const HEY = 'https://heyresearch.xyz';

// One line under a contract's address on an explorer page.
async function heyExplorerLine(token) {
  const r = await fetch(`${HEY}/api/v1/builder?chain=4663&token=${token}`, {
    headers: { 'x-hey-integration': 'my-explorer/1.0.0' },
  });
  if (!r.ok) return null;
  const c = await r.json();
  const verification = { VERIFIED: 'named by the project', UNVERIFIED: 'not yet named by the project', MISMATCH: 'the project names another contract' };
  let text = 'HEY: ' + verification[c.token_verification];
  if (c.activity_applies_to_token) {
    text += ' · builder ' + c.hey_status_label.toLowerCase();
    if (c.latest_meaningful_ship) text += ' · last ship ' + c.latest_meaningful_ship.timestamp.slice(0, 10);
  }
  return { text, href: c.activity_applies_to_token ? c.project_link : null };
}

Project directory

A page of listings, thirty tokens in one keyed call.

const HEY = 'https://heyresearch.xyz';

// A page of up to 30 tokens in one keyed call (the scan card's bulk form).
async function heyDirectoryRows(tokens, apiKey) {
  const r = await fetch(`${HEY}/api/v1/scan?chain=4663&tokens=${tokens.join(',')}`, {
    headers: { authorization: 'Bearer ' + apiKey, 'x-hey-integration': 'my-directory/1.0.0' },
  });
  if (!r.ok) return [];
  const { items } = await r.json();
  return items.map((item) => {
    if (!item.found) return { token: item.input, label: null, href: null }; // not indexed: print nothing
    return {
      token: item.input,
      label: item.status_label + (item.verified_builder ? ' · Verified Builder' : ''),
      // Absent means unknown: only a measured count is a number.
      ships30d: item.activity.meaningful_ships_30d ?? null,
      href: item.activity_applies_to_token ? item.project_link : null,
    };
  });
}

AI agent

A tool an assistant calls, answering in facts with evidence ids.

const HEY = 'https://heyresearch.xyz';

// A tool an agent can call. The answer restates HEY; it never adds a verdict.
const heyBuilderTool = {
  name: 'hey_builder_card',
  description: 'Who is building a Robinhood Chain token, what they shipped and HEY\'s evidence. Not a rating, not a price signal.',
  input_schema: { type: 'object', properties: { token: { type: 'string', pattern: '^0x[0-9a-fA-F]{40}$' } }, required: ['token'] },
};

async function heyBuilderToolCall({ token }) {
  const r = await fetch(`${HEY}/api/v1/builder?chain=4663&token=${token}`, {
    headers: { 'x-hey-integration': 'my-agent/0.1.0' },
  });
  if (r.status === 404) return 'HEY has not published a project for this contract. That says nothing about the token.';
  if (!r.ok) return 'HEY did not answer; say nothing about the builder.';
  const c = await r.json();
  const facts = [
    'Project: ' + c.hey_project_name + ' (' + c.hey_project_url + ')',
    'Token named by the project: ' + c.token_verification + (c.activity_applies_to_token ? '' : ' - do not attribute the activity to this token'),
    'Builder status: ' + c.hey_status_label + (c.activity_measured ? '' : ' (building not measured)'),
    'Verified Builder: ' + (c.verified_builder ? 'yes' : 'no'),
    'Meaningful ships, 30d: ' + (c.meaningful_ships_30d === null ? 'unknown' : c.meaningful_ships_30d),
  ];
  if (c.latest_meaningful_ship) facts.push('Latest ship: ' + c.latest_meaningful_ship.title + ' at ' + c.latest_meaningful_ship.timestamp + ' [' + c.latest_meaningful_ship.evidence_id + ']');
  if (c.latest_change) facts.push('Latest change: ' + c.latest_change.summary + (c.latest_change.evidence_id ? ' [' + c.latest_change.evidence_id + ']' : ''));
  facts.push('Scored: ' + (c.as_of ?? 'never'), 'Cite: ' + c.project_link, c.disclaimer);
  return facts.join('\n');
}

Rate limits and keys

Read from the limits this deployment enforces. Answers are cached for 60 seconds, so polling faster gains nothing. On a 429, wait the retry-after seconds and print nothing meanwhile.

  • No key

    120 / min · no monthly cap

    Per client address. Enough for a bot answering lookups; the bulk scan form needs a key.

  • Free key

    120 / min · 10,000 / month

    From your account, in a minute, with no holding. Names your product to HEY and unlocks the bulk scan; the per-minute limit is the same as no key.

  • Holder key

    600 / min · 50,000 / month

    An account whose linked wallet meets the Holder tier.

  • Holder+ key

    1,200 / min · 250,000 / month

    An account whose linked wallet meets the Holder+ tier.

  • Partner key

    agreed per partner · agreed per partner

    For a product whose readers need more: its own quota, recorded by HEY. Ask below; it is never paid for and changes nothing HEY says.

Issue a free key at your account and send it as authorization: Bearer hey_…. A keyed answer carries x-hey-monthly-remaining.

One line by contract

A bot that answers with one line needs only /api/token/4663/{contract}: the call, the line to render from it, the three answers to handle and the four things not to do are in Putting HEY in your bot. For a product card, the Partner Card above.

A credit, never a ranking

A product that reads HEY and names itself on its calls (the x-hey-integration header) is credited on Built with HEY, alphabetically, with no count — once HEY has recorded it as a partner with its public site. Write to say which name you send. Being listed changes nothing HEY says about any project.

Say who you are, and link the evidence

  • Name your integration. Send x-hey-integration: your-product/1.4.0, or add integration=your-product/1.4.0 to the URL. Lower-case letters, digits, ., _ and -, an optional /version. It is optional and a self-declaration, never an identity; anything else is ignored. Use your product’s own name: the example names on this page (your-product, my-product) and names starting hey- are never counted as an integration. A name sent with no key is observed and never counted as a partner; a key is what makes a caller one.
  • Link project_link. It is the project page with utm_source=your-product (or hey_api when you named none), utm_medium=partner_api and utm_campaign=builder_card, so HEY can tell you how many readers followed it. hey_project_url stays the bare canonical URL, and so does the scan card’s cta.url: if your card renders cta, link project_link behind it.
  • What HEY records. Per request: the route, the status, the name you declared, the project the answer was about, and a caller digest salted daily. No address, no user agent, no person. A key, from your account, is what identifies a partner.
  • Every answer is private. The partner cards answer private, max-age=60 whichever form names you, so every call reaches HEY and is counted; keep an answer in your own cache for a minute.

Run a protocol on Robinhood Chain?

When your protocol holds a public fact about a token — a lock, a launch, a hook — HEY can print it as a stamp on that token’s page, crediting your protocol by name with a link. It is free and changes nothing HEY says about any project. How the Token Passport works

Need more than this page gives?

A higher quota, a partner key, a field you need and do not see, or a card that reads wrong: write to hi@heyresearch.xyz with your product’s name and the call you make. Nothing about it is paid, and a partnership changes nothing HEY says about any project.