Skip to main content
The crosschain.agents.erc8004_events table contains all decoded ERC-8004 protocol events across 6 mainnets. Each row is a single event — registrations, metadata updates, feedback submissions, revocations, and responses are all captured in a unified schema with event-specific fields stored in the extra_fields VARIANT column. Per-chain tables (e.g., ethereum.agents.erc8004_events) share the same schema. See the protocol overview for the full list.

Table Details

PropertyValue
Table Namecrosschain.agents.erc8004_events
Table StatusProduction-Ready
Unique Keytransaction_hash, log_index
Clustering Key(s)to_date(block_timestamp), event_name

Table Columns

Column NameData TypeDescription
event_nameVARCHAREvent type: Registered, URIUpdated, MetadataSet, NewFeedback, FeedbackRevoked, ResponseAppended
agent_idVARCHARNumeric agent NFT ID.
chainVARCHARNetwork name (ethereum, base, polygon, scroll, bsc, gnosis).
registry_typeVARCHARRegistry type: identity or reputation.
registry_addressVARCHARRegistry contract address.
registry_nameVARCHARRegistry name: IdentityRegistry or ReputationRegistry.
is_officialBOOLEANWhether the event is from an official ERC-8004 registry.
extra_fieldsVARIANTEvent-specific decoded parameters as JSON (see below).
block_timestampTIMESTAMP_NTZ(9)The timestamp when the event occurred.
transaction_hashVARCHARThe transaction hash containing this event.
transaction_from_addressVARCHARThe address of the transaction signer.
transaction_to_addressVARCHARThe address of the transaction recipient.
block_numberNUMBER(38,0)The block number containing this event.
block_hashVARCHARThe hash of the block containing this event.
log_indexNUMBER(38,0)The position of the event log within the transaction.
unique_idVARCHARUnique identifier for the event.
_created_atTIMESTAMP_NTZ(9)The timestamp when the record was created.
_updated_atTIMESTAMP_NTZ(9)The timestamp when the record was last updated.

extra_fields by Event Type

EventKeyTypeDescription
RegisteredcreatorSTRINGAddress that registered the agent.
RegisteredwalletSTRINGAgent’s wallet address.
URIUpdateduriSTRINGNew metadata URI.
MetadataSetkeySTRINGMetadata key.
MetadataSetvalueSTRINGMetadata value.
NewFeedbackclientAddressSTRINGAddress of the rater.
NewFeedbackvalueINTFeedback score (0-100).
NewFeedbackvalueDecimalsINTDecimal places for score normalization.
NewFeedbacktag1STRINGPrimary feedback tag.
NewFeedbacktag2STRINGSecondary feedback tag.
NewFeedbackfeedbackURISTRINGURI containing feedback details (often base64-encoded JSON).
NewFeedbackfeedbackHashSTRINGHash of feedback content.
NewFeedbackfeedbackIndexINTIndex of feedback for this agent.
NewFeedbackendpointSTRINGAPI endpoint being rated.
FeedbackRevokedclientAddressSTRINGAddress of the rater who revoked.
FeedbackRevokedfeedbackIndexINTIndex of revoked feedback.
ResponseAppendedresponseURISTRINGURI of agent’s response to feedback.
Access extra_fields using Snowflake semi-structured syntax:
extra_fields:clientAddress::STRING    -- rater address
extra_fields:value::INT               -- feedback score
extra_fields:tag1::STRING             -- primary tag

Example Queries

Protocol KPIs

SELECT
    COUNT(DISTINCT CASE WHEN event_name = 'Registered'
          THEN chain || '-' || agent_id END) AS total_agents,
    COUNT(CASE WHEN event_name = 'NewFeedback' THEN 1 END) AS total_feedback,
    COUNT(DISTINCT CASE WHEN event_name = 'NewFeedback'
          THEN extra_fields:clientAddress::STRING END) AS unique_raters,
    ROUND(AVG(CASE WHEN event_name = 'NewFeedback'
        THEN extra_fields:value::FLOAT
             / NULLIF(POW(10, COALESCE(extra_fields:valueDecimals::INT, 0)), 0)
        END), 1) AS avg_feedback_score,
    ROUND(COUNT(CASE WHEN event_name = 'FeedbackRevoked' THEN 1 END) * 100.0
          / NULLIF(COUNT(CASE WHEN event_name = 'NewFeedback' THEN 1 END), 0), 3)
        AS revocation_rate_pct
FROM crosschain.agents.erc8004_events;

Daily Registrations by Chain

SELECT
    DATE_TRUNC('day', block_timestamp)::DATE AS dt,
    chain,
    COUNT(DISTINCT agent_id) AS agents_registered
FROM crosschain.agents.erc8004_events
WHERE event_name = 'Registered'
GROUP BY ALL
ORDER BY dt;

Chain Distribution

SELECT
    chain,
    COUNT(DISTINCT CASE WHEN event_name = 'Registered' THEN agent_id END) AS agents,
    COUNT(CASE WHEN event_name = 'NewFeedback' THEN 1 END) AS feedback_count,
    COUNT(DISTINCT CASE WHEN event_name = 'NewFeedback'
          THEN extra_fields:clientAddress::STRING END) AS unique_raters,
    ROUND(AVG(CASE WHEN event_name = 'NewFeedback'
          THEN extra_fields:value::FLOAT END), 1) AS avg_score
FROM crosschain.agents.erc8004_events
GROUP BY chain
ORDER BY agents DESC;

Feedback Score Distribution

WITH scores AS (
    SELECT extra_fields:value::INT AS score
    FROM crosschain.agents.erc8004_events
    WHERE event_name = 'NewFeedback' AND extra_fields:value IS NOT NULL
)
SELECT
    CASE
        WHEN score BETWEEN 0 AND 10 THEN '0-10'
        WHEN score BETWEEN 11 AND 20 THEN '11-20'
        WHEN score BETWEEN 21 AND 30 THEN '21-30'
        WHEN score BETWEEN 31 AND 40 THEN '31-40'
        WHEN score BETWEEN 41 AND 50 THEN '41-50'
        WHEN score BETWEEN 51 AND 60 THEN '51-60'
        WHEN score BETWEEN 61 AND 70 THEN '61-70'
        WHEN score BETWEEN 71 AND 80 THEN '71-80'
        WHEN score BETWEEN 81 AND 90 THEN '81-90'
        WHEN score BETWEEN 91 AND 100 THEN '91-100'
    END AS score_range,
    COUNT(*) AS feedbacks,
    ROUND(COUNT(*) * 100.0 / SUM(COUNT(*)) OVER (), 1) AS pct_of_total
FROM scores
GROUP BY ALL
ORDER BY score_range;

Top Agents Leaderboard

WITH agent_stats AS (
    SELECT
        agent_id,
        chain,
        COUNT(CASE WHEN event_name = 'NewFeedback' THEN 1 END) AS feedback_count,
        AVG(CASE WHEN event_name = 'NewFeedback'
            THEN extra_fields:value::FLOAT END) AS avg_score,
        COUNT(CASE WHEN event_name = 'ResponseAppended' THEN 1 END) AS response_count,
        MIN(CASE WHEN event_name = 'Registered'
            THEN block_timestamp END) AS registered_at
    FROM crosschain.agents.erc8004_events
    GROUP BY agent_id, chain
    HAVING feedback_count > 0
)
SELECT
    agent_id, chain, feedback_count,
    ROUND(avg_score, 1) AS avg_score,
    response_count,
    registered_at::DATE AS registered_date
FROM agent_stats
ORDER BY feedback_count DESC
LIMIT 25;

Decode Feedback Comments

Some feedback includes base64-encoded JSON with human-readable comments:
SELECT
    agent_id, chain,
    extra_fields:clientAddress::STRING AS rater,
    extra_fields:value::INT AS score,
    extra_fields:tag1::STRING AS tag1,
    TRY_PARSE_JSON(TRY_BASE64_DECODE_STRING(
        SPLIT_PART(extra_fields:feedbackURI::STRING, ',', 2)
    )):comment::STRING AS comment,
    block_timestamp::DATE AS feedback_date
FROM crosschain.agents.erc8004_events
WHERE event_name = 'NewFeedback'
  AND extra_fields:feedbackURI::STRING LIKE 'data:application/json;base64,%'
ORDER BY block_timestamp DESC
LIMIT 50;

Reputation Trend (Multi-Metric Daily)

SELECT
    DATE_TRUNC('day', block_timestamp)::DATE AS dt,
    COUNT(CASE WHEN event_name = 'NewFeedback' THEN 1 END) AS new_feedback,
    COUNT(CASE WHEN event_name = 'FeedbackRevoked' THEN 1 END) AS revoked,
    COUNT(CASE WHEN event_name = 'ResponseAppended' THEN 1 END) AS responses,
    COUNT(DISTINCT CASE WHEN event_name = 'NewFeedback'
          THEN extra_fields:clientAddress::STRING END) AS unique_raters
FROM crosschain.agents.erc8004_events
WHERE event_name IN ('NewFeedback', 'FeedbackRevoked', 'ResponseAppended')
GROUP BY ALL
ORDER BY dt;