ReplyWeb API Documentation

Introduction

Welcome to the ReplyWeb API documentation. This guide will help you integrate conversion tracking and leaderboard functionality into your application.

Table of Contents


Getting Started

API Version

Current Version: v1.4.3

Base URL

All API requests should be made to:

Prerequisites

Before you can use the ReplyWeb API, you need to:

  1. Register an organization account

  2. Obtain your API key

  3. Create a campaign


Authentication

Step 1: Request Access

Important: Organization registration requires email whitelisting. Before you can register, your email address must be approved by an administrator.

To request access, please contact support at [email protected]envelope with:

  • Your organization name

  • Your email address (this will be used as the admin email)

  • Brief description of your use case

Once your email is whitelisted, you can proceed with registration.

Step 2: Register Your Organization

After your email has been whitelisted, register your organization and receive an API key.

Endpoint: POST /api/v1/auth/register

Request Body:

Example Request:

Error Response (403 Forbidden) - Email Not Whitelisted:

Success Response:

Important: Save your apiKey securely. You'll need it for all API requests.

Note: If you receive a 403 error indicating your email is not whitelisted, please contact support to request access before attempting registration again.

Step 3: Login (Alternative Method)

If you already have an account, you can log in to retrieve your API key.

Endpoint: POST /api/v1/auth/login

Request Body:

Example Request:

Response:

Note: To retrieve your API key after login, you'll need to make an authenticated request to get your organization details.

Step 4: Using Your API Key

Once you have your API key, include it in all API requests using the X-API-Key header:

API Key Format:

  • Format: rweb_{plan-tier}_{organization-slug}_{random-string}

  • Plan tiers: basic, standard, professional, enterprise

  • Examples:

    • rweb_basic_replycorp_tGF9jIsFpQJPkcUUwQqkaYqG (Basic plan)

    • rweb_standard_replycorp_tGF9jIsFpQJPkcUUwQqkaYqG (Standard plan)

    • rweb_professional_replycorp_tGF9jIsFpQJPkcUUwQqkaYqG (Professional plan)

    • rweb_enterprise_replycorp_tGF9jIsFpQJPkcUUwQqkaYqG (Enterprise plan)

  • The tier prefix indicates your organization's subscription plan level


Conversion Tracking

Overview

The conversion tracking API allows you to record purchases or other conversion events. When a conversion is recorded, ReplyWeb automatically:

  1. Identifies the buyer's Twitter/X account

  2. Calculates attribution to influencers who drove the conversion

  3. Distributes points to attributed influencers (positive for positive events, negative for negative events)

  4. Updates the leaderboard rankings based on net volume

Event Types

The API supports multiple event types to track both positive and negative events:

Positive Events (require positive amount):

  • lock - REPPO tokens locked

  • buy - Tokens purchased

  • purchase - Purchase made (default if eventType is omitted)

Negative Events (require negative amount):

  • unlock - REPPO tokens unlocked

  • sell - Tokens sold

  • refund - Purchase refunded

Net Volume Calculation:

  • Leaderboards calculate net volume by summing all conversion values (locks minus unlocks, purchases minus refunds)

  • Attribution points are distributed as positive points for positive events and negative points for negative events

  • This maintains accurate net attribution tracking

Post a Conversion

Endpoint: POST /api/v1/campaigns/{campaignId}/conversions

Authentication: Required (API Key)

Request Headers:

Request Body:

Field Descriptions:

Field
Type
Required
Description

twitterId

string

Yes

The Twitter/X user ID of the person who made the purchase/lock/unlock

eventType

string

No

Event type: lock, unlock, buy, sell, purchase, refund. Defaults to purchase if omitted (backward compatibility)

amount

number

Yes

The event amount. Must be positive for lock/buy/purchase, negative for unlock/sell/refund

walletAddress

string

No

Optional wallet address (EVM or Solana) associated with the buyer

metadata

object

No

Optional metadata object for storing additional conversion data. Will be merged with server-generated metadata (eventType, walletAddress). Server fields take precedence if conflicts occur

metadata.txHash

string

Yes (for lock/unlock)

Unique transaction hash identifying the lock. Required for lock and unlock events to enable expiry tracking and prevent duplicate unlocks

metadata.expiresAt

number

No (for lock)

Expiry timestamp in epoch seconds. When provided for lock events, the system will automatically create an unlock event at expiry time if the lock hasn't been manually unlocked

metadata.userId

string

No

Optional user identifier (e.g., Privy user ID)

Example Requests:

Positive Event (Lock with Expiry):

Negative Event (Manual Unlock):

Backward Compatible (Purchase - no eventType):

With Custom Metadata:

Success Response (201 Created):

Response Fields:

Field
Description

conversion.id

Unique identifier for the conversion

conversion.conversionType

Type of conversion event (lock, unlock, buy, sell, purchase, refund)

conversion.eventType

Event type (same as conversionType, included for clarity)

conversion.conversionValue

The event amount (positive for positive events, negative for negative events)

conversion.convertedAt

ISO 8601 timestamp of when the conversion was recorded

conversion.participant

Participant information for the user who triggered the event

conversion.participant.id

Unique identifier for the participant

conversion.participant.twitterId

Twitter/X user ID

conversion.participant.twitterHandle

Twitter/X handle

conversion.participant.hasEngaged

Boolean indicating if the buyer has actually engaged with tagged posts (commented, replied, or engaged with posts mentioning your campaign). Only counts actual post interactions, not other ways of joining the campaign.

conversion.participant.hasConnected

Boolean indicating if the buyer has connected their X account and wallet

attribution.pointsDistributed

Boolean indicating if points were distributed to influencers

attribution.totalPointsDistributed

Total points distributed (positive for positive events, negative for negative events)

attribution.firstDegreeCount

Number of 1st degree connections that received attribution

attribution.secondDegreeCount

Number of 2nd degree connections that received attribution

attribution.attributions

Array of detailed attribution information for each attributed user (new in v1.1.0)

attribution.attributions[].twitterId

X (Twitter) account ID of the attributed user

attribution.attributions[].twitterHandle

X (Twitter) handle of the attributed user

attribution.attributions[].walletAddress

Wallet address if connected, null if not connected

attribution.attributions[].attributedAmount

Dollar amount attributed to this user (positive for positive events, negative for negative events)

attribution.attributions[].attributionPercentage

Percentage of transaction amount attributed to this user (0-100, always positive)

attribution.attributions[].degree

Attribution degree: 1 for 1st degree connections, 2 for 2nd degree connections

attribution.eligibleAttributions

Array of attributions filtered by threshold (if enabled), with percentages recalculated to sum to 100% across eligible users only (new in v1.4.1)

attribution.eligibleAttributions[].twitterId

X (Twitter) account ID of the eligible attributed user

attribution.eligibleAttributions[].twitterHandle

X (Twitter) handle of the eligible attributed user

attribution.eligibleAttributions[].walletAddress

Wallet address if connected, null if not connected

attribution.eligibleAttributions[].attributedAmount

Dollar amount attributed to this user (same as in attributions array)

attribution.eligibleAttributions[].attributionPercentage

Recalculated percentage that sums to 100% across eligible users only

attribution.eligibleAttributions[].degree

Attribution degree: 1 for 1st degree connections, 2 for 2nd degree connections

Attributions Array Details:

The attributions array provides detailed information for each user who received attribution from the conversion. This enables partners to calculate revenue share payouts.

Key Features:

  • Wallet Addresses: Returns wallet address if the user has connected their wallet, null otherwise

  • Percentage Calculation: Percentage is always positive (0-100), even for negative events (unlock, sell, refund)

  • Attributed Amount: Can be negative for negative events (unlock, sell, refund)

  • Empty Array: Returns empty array [] when there are no attributions (isolated users)

Handling Missing Wallet Addresses:

When walletAddress is null, partners can:

  1. Match wallet address on their side: If they have a wallet linked to the X account, they can map it directly

  2. Hold rewards in smart contract: Escrow rewards for a fixed period (e.g., 30 days) until wallet address is provided

  3. Register webhook for updates: Receive webhook notifications when participants register or update their wallet address (coming soon)

Payout Calculation Example:

Eligible Attributions (Threshold Filtering):

When a campaign has rewardThreshold set in its customBranding metadata, the response includes an eligibleAttributions array. This array contains only users who meet the minimum cumulative attribution points threshold (same threshold used for weekly rewards eligibility). If rewardThreshold is not set (or is null/undefined), eligibleAttributions will be an empty array.

Key Features:

  • Threshold Check: Users must have cumulative total attribution points >= rewardThreshold (from customBranding) across all conversions in the campaign

  • Recalculated Percentages: Percentages in eligibleAttributions are recalculated to sum to 100% across eligible users only

  • Original Amounts Preserved: attributedAmount values remain the same as in the attributions array

  • Empty Array: Returns empty array [] when rewardThreshold is not set or no users meet the threshold

  • Same Threshold: Uses the same rewardThreshold value configured in "Edit Campaign Metadata" for weekly rewards eligibility

Example with Threshold Enabled:

If a campaign has customBranding.rewardThreshold: 100 and a conversion has 3 attributions:

  • User A: 150 cumulative points → Eligible

  • User B: 50 cumulative points → Not eligible

  • User C: 200 cumulative points → Eligible

The eligibleAttributions array will contain only User A and User C, with percentages recalculated to sum to 100%.

Error Responses:

400 Bad Request - Invalid request body:

400 Bad Request - Invalid event type:

400 Bad Request - Amount sign mismatch:

400 Bad Request - Zero amount:

400 Bad Request - Invalid metadata:

400 Bad Request - Missing txHash for lock event:

400 Bad Request - Missing txHash for unlock event:

400 Bad Request - Invalid expiresAt:

400 Bad Request - ExpiresAt in the past:

400 Bad Request - Lock not found for unlock:

409 Conflict - Lock already unlocked:

401 Unauthorized - Missing or invalid API key:

403 Forbidden - Email not whitelisted (registration) or campaign belongs to different organization:

403 Forbidden - Campaign belongs to different organization:

404 Not Found - Campaign not found:

409 Conflict - Duplicate conversion:

500 Internal Server Error:

How Attribution Works

When you post a conversion:

  1. Buyer Identification: The system looks up the buyer by their twitterId in your campaign's participant list.

  2. Attribution Calculation: If the buyer is a participant, the system identifies all of their 1st and 2nd degree connections. Attribution is distributed to all connections based on their degree of separation.

  3. Points Distribution:

    • Attribution Modes: Campaigns can use one of two attribution modes (configured via attributionConfig.pointsSplitMode):

      • Whole Mode (default): Each participant gets 100% of the conversion amount attributed to them

      • Split Mode: Attribution is split between upstream (influencers) and downstream (influenced) pools, then distributed proportionally

    • Positive Events (lock, buy, purchase):

      • Points are calculated at 10 points per $1 for 1st degree connections (default)

      • Points are calculated at 1.5 points per $1 for 2nd degree connections (default)

      • Example (Whole Mode): A $123.45 lock = 1,235 points to each 1st degree connection, 185 points to each 2nd degree connection

      • Example (Split Mode): A $100 conversion with 80/20 split and 10 upstream 1st degree connections (8 with Person A, 2 with Person B):

        • Upstream pool: $80

        • Each connection: $80 × (1.0 / 10.0) = $8.00

        • Person A: 8 × $8.00 = $64.00 attribution

        • Person B: 2 × $8.00 = $16.00 attribution

    • Negative Events (unlock, sell, refund):

      • Negative points are distributed using the same rates and mode

      • Example: A -$50.00 unlock = -500 points to 1st degree, -75 points to 2nd degree (in whole mode)

      • This maintains net attribution tracking (positive points offset by negative points)

    • Points are automatically distributed to all attributed influencers based on their connection degree and campaign configuration

  4. Net Volume Calculation:

    • Leaderboards calculate net volume by summing all conversionValue amounts

    • Example: $100 lock + (-$30 unlock) = $70 net volume

    • Attribution points are summed to get net points per influencer

  5. Leaderboard Update: The leaderboard is automatically updated to reflect the new attribution and points for all participating influencers.

Note: If the buyer is not yet a participant in your campaign, a participant record will be created automatically, but no attribution will be calculated until they have connections in the network.

Split Mode Benefits: Split mode prevents point dilution when many people comment on comment threads. Instead of each participant getting 100% attribution, the conversion amount is split proportionally among all connections, ensuring that participants with more connections (more influence paths) receive proportionally more attribution.

Lock Expiry and Auto-Unlock

For lock events with expiry timestamps:

  1. Lock Creation: When a lock event is received with metadata.expiresAt, the system schedules a background job to process the expiry exactly when the lock expires.

  2. Manual Unlock: If a manual unlock event is received before expiry, the scheduled expiry job is automatically canceled to prevent duplicate unlock events.

  3. Automatic Expiry: When a lock expires:

    • The system checks if the lock has already been manually unlocked

    • If not unlocked, an automatic unlock event is created with metadata.expired: true

    • Attribution points are distributed (negative points to offset the original lock)

    • The unlock event is processed exactly at expiry time (or very close, depending on Redis/BullMQ precision)

  4. Duplicate Prevention: The system prevents duplicate unlocks by:

    • Requiring txHash for both lock and unlock events

    • Checking for existing unlock events before creating new ones

    • Canceling scheduled expiry jobs when manual unlocks occur

    • Using database transactions to handle race conditions

Example Lock Expiry Flow:

  • Lock created with expiresAt: 1735689600 (3 months from now)

  • System schedules job to execute at that timestamp

  • If user manually unlocks before expiry → scheduled job is canceled

  • If lock expires without manual unlock → auto-unlock event created automatically

Backward Compatibility

The API maintains full backward compatibility with existing integrations:

  • Omitting eventType: If eventType is not provided, it defaults to "purchase"

  • Positive amounts only: When eventType is omitted, the API still requires positive amounts (existing behavior)

  • Response format: The response includes both conversionType and eventType fields, but existing consumers can continue using conversionType

Campaign Points Configuration

ReplyWeb uses a temporal, append-only configuration system for campaign points settings. This design provides several powerful capabilities:

How It Works:

  • Campaign points configurations are stored in a database table with rows for each campaign

  • When you update attribution settings, new rows are added instead of updating existing ones

  • The system always uses the current active configuration when calculating attribution

  • All historical configurations are preserved for analysis and backtesting

Key Benefits:

  1. Temporal Queries: You can query attribution calculations as they were at any point in time. When a conversion is recorded, the system uses the active configuration at that moment, and you can later see exactly what configuration was applied.

  2. Multi-Layer Functionality: The degreeOfAttribution becomes a field in each configuration row, not a global constant. This means you can have different attribution degrees for different connection layers (1st degree, 2nd degree, etc.) and change them independently over time.

  3. Complete History: Every configuration change is preserved, allowing you to:

    • See how attribution rules evolved over time

    • Backtest different configurations to model outcomes

    • Audit attribution decisions by viewing the exact configuration that was active when each conversion was recorded

    • Compare the impact of different attribution strategies

Example Use Case:

If you change your attribution configuration from "first degree only" to "first and second degree with 50/50 split", the new configuration is added as a new row. All conversions recorded after that point will use the new configuration, while conversions recorded before will retain their original attribution based on the previous configuration. This allows you to analyze the impact of the change and even model what would have happened if you had used different settings.

Integration Examples

JavaScript/Node.js

Python

PHP


Leaderboard Integration

Overview

The leaderboard API allows you to retrieve ranked lists of participants in your campaign. There are two leaderboard endpoints:

  1. Standard Leaderboard - Shows participants ranked by connections

  2. Leaderboard Pull - Shows participants ranked by attributed sales and points (recommended for most use cases)

The leaderboard pull endpoint shows participants ranked by their attributed sales and points, making it ideal for displaying top performers who are driving conversions.

Endpoint: GET /api/v1/campaigns/{campaignId}/leaderboard-pull

Authentication: Optional (Public if campaign leaderboard is public)

Query Parameters:

Parameter
Type
Default
Description

page

integer

1

Page number (1-indexed)

limit

integer

100

Number of results per page (max 100)

Example Request:

Note: If your campaign's leaderboard is set to public, you can omit the API key header.

Success Response (200 OK):

Response Fields:

Field
Description

campaign.id

Campaign identifier

campaign.name

Campaign name

holders[].rank

Participant's rank (1 = highest)

holders[].userId

Unique user identifier

holders[].attributedSales

Total attributed sales amount (rounded to integer)

holders[].xAccount

Twitter/X handle

holders[].email

Email address (if provided during registration)

holders[].evmWallet

EVM wallet address (if available)

holders[].solanaWallet

Solana wallet address (if available)

holders[].points

Total points earned from attributed conversions

pagination.currentPage

Current page number

pagination.totalPages

Total number of pages

pagination.totalItems

Total number of participants

pagination.hasNextPage

Whether there are more pages

pagination.hasPrevPage

Whether there are previous pages

Get Standard Leaderboard

The standard leaderboard shows participants ranked by their connection counts.

Endpoint: GET /api/v1/campaigns/{campaignId}/leaderboard

Authentication: Optional (Public if campaign leaderboard is public)

Query Parameters:

Parameter
Type
Default
Description

page

integer

1

Page number (1-indexed)

limit

integer

50

Number of results per page (max 100)

sortBy

string

"firstDegreeConnections"

Sort field: firstDegreeConnections, secondDegreeConnections, enteredAt, twitterHandle

order

string

"desc"

Sort order: asc or desc

Example Request:

Success Response (200 OK):

Embedding the Leaderboard in Your App

Option 1: Fetch and Display (Recommended)

Fetch the leaderboard data and display it in your own UI:

JavaScript/React Example:

HTML/JavaScript Example:

Option 2: Public Leaderboard (No API Key Required)

If your campaign's leaderboard is set to public, you can fetch it without an API key:

Note: To make your leaderboard public, configure this setting in your campaign dashboard.


Error Handling

Common Error Codes

Status Code
Meaning
Description

400

Bad Request

Invalid request parameters or body

401

Unauthorized

Missing or invalid API key

403

Forbidden

Access denied (e.g., campaign belongs to different organization)

404

Not Found

Resource not found (campaign, participant, etc.)

409

Conflict

Duplicate conversion or resource conflict

500

Internal Server Error

Server error occurred

Error Response Format

All error responses follow this format:

Handling Errors in Your Code

JavaScript Example:


Rate Limits

Current Limits

  • Conversion API: No specific rate limit (subject to fair use)

  • Leaderboard API: No specific rate limit (subject to fair use)

Best Practices

  1. Cache Leaderboard Data: Leaderboard data doesn't change frequently. Cache it for 1-5 minutes to reduce API calls.

  2. Batch Conversions: If recording multiple conversions, make sequential requests rather than parallel to avoid overwhelming the system.

  3. Error Retry: Implement exponential backoff for retries on 500 errors.

Example Retry Logic:


Support

Getting Help

Reporting Issues

When reporting issues, please include:

  1. API endpoint you're calling

  2. Request headers (mask your API key)

  3. Request body

  4. Response status code and body

  5. Timestamp of the request


Changelog

Version 1.4.3 (January 8, 2026)

  • Participant Engagement and Connection Status: Added participant status fields to conversion endpoint response

    • New hasEngaged field in conversion.participant: Boolean indicating if the buyer has actually engaged with tagged posts (commented, replied, or engaged with posts mentioning your campaign). Only counts actual post interactions (ReplyWebEvent records), not other ways of joining the campaign.

    • New hasConnected field in conversion.participant: Boolean indicating if the buyer has connected their X account and wallet (CampaignRegistrant exists with walletConnectedAt)

    • Enables comment & connect incentive feature for customers to reward buyers who have engaged with posts and connected before purchasing

    • Fully backward compatible - existing response fields preserved

Version 1.4.2 (January 6, 2026)

  • Auto Messages Control: Added campaign-level control for automatic messages on X (Twitter)

    • New autoMessagesEnabled field in campaign configuration (default: false)

    • When false, campaigns will not send automatic rank replies or welcome messages on X

    • When true, campaigns will send automatic messages as configured

    • Plan Restriction: BASIC plan accounts cannot enable auto messages (feature unavailable)

    • STANDARD, PROFESSIONAL, and ENTERPRISE plans can toggle auto messages on/off

    • Configured via campaign update endpoint (PATCH /api/v1/campaigns/:id) or admin dashboard

    • Existing campaigns on non-BASIC plans default to true (backward compatible)

    • Existing campaigns on BASIC plans default to false (feature unavailable)

Version 1.4.1 (January 6, 2026)

  • Attribution Points Threshold: Added campaign-level threshold filtering for attribution eligibility

    • Uses existing rewardThreshold field from customBranding metadata (same threshold used for weekly rewards eligibility)

    • New eligibleAttributions array in conversion response: contains only users who meet the threshold (only present when rewardThreshold is set)

    • Percentages in eligibleAttributions are recalculated to sum to 100% across eligible users only

    • Threshold is based on cumulative attribution points across all conversions in the campaign

    • Returns empty eligibleAttributions array when rewardThreshold is not set or no users meet the threshold

    • Fully backward compatible - existing attributions array unchanged

    • Configured via "Edit Campaign Metadata" page (no separate threshold field needed)

Version 1.4.0 (January 6, 2026)

  • Attribution Payout Schema: Added detailed attribution information to conversion endpoint response

    • New attributions array in attribution object containing detailed information for each attributed user

    • Each attribution includes: twitterId, twitterHandle, walletAddress, attributedAmount, attributionPercentage, and degree

    • Enables partners to calculate revenue share payouts programmatically

    • walletAddress is null when user hasn't connected their wallet

    • Attribution percentages are always positive (0-100), even for negative events

    • Empty attributions return empty array [] for isolated users

    • Fully backward compatible - all existing response fields preserved

Version 1.3.0 (December 30, 2025)

  • Attribution Split Configuration: Added campaign-level configuration to split attribution points between upstream and downstream participants

    • New pointsSplitMode field in attributionConfig: "whole" (default) or "split"

    • New pointsSplitConfig object with configurable ratios:

      • upstreamRatio (default: 0.8) and downstreamRatio (default: 0.2) - must sum to 1.0

      • degreeWeights with first (default: 1.0) and second (default: 0.15) multipliers

    • Split mode prevents point dilution when many people comment on comment threads

    • Attribution is calculated per-connection first, then aggregated by participant

    • Backward compatible: defaults to "whole" mode for existing campaigns

    • Updated campaign update endpoint (PATCH /api/v1/campaigns/:id) to support new configuration fields

Version 1.2.0 (December 26, 2025)

  • Lock Expiry and Auto-Unlock: Added automatic expiry handling for lock events

    • Lock events now support metadata.txHash (required) and metadata.expiresAt (optional, epoch seconds)

    • Unlock events now require metadata.txHash to reference the lock being unlocked

    • System automatically creates unlock events when locks expire if they haven't been manually unlocked

    • Manual unlocks cancel scheduled expiry jobs to prevent duplicate unlocks

    • Expiry jobs are processed exactly at expiry time using BullMQ delayed jobs

Version 1.1.0 (December 19, 2025)

  • Event-Based Conversion API: Added support for multiple event types (lock, unlock, buy, sell, purchase, refund) with positive and negative amounts

  • Depositor Count Tracking: Added depositorCount field to leaderboard-pull endpoint for legacy campaigns, tracking unique depositors per participant

  • Enhanced Registrants Endpoint: Updated /registrants/user endpoint to:

    • Return connection data (firstDegree, secondDegree, total) using the same calculation method as leaderboard

    • Include attribution data (attributedSales, points) calculated using calculateAttributionScore (same as leaderboard)

    • Include depositorCount in attribution response for legacy campaigns

    • Ensure consistency between leaderboard and user profile data

Version 1.0.0

  • Initial release of ReplyWeb API

  • Conversion tracking endpoint

  • Leaderboard endpoints (standard and pull)

  • API key authentication

  • Public leaderboard support


Appendix

Campaign ID Format

Campaign IDs are UUIDs in the format:

Twitter ID Format

Twitter/X user IDs are numeric strings:

To get a user's Twitter ID, you can use Twitter's API or third-party tools.

Wallet Address Formats

  • EVM Wallets: Start with 0x and are 42 characters long

    • Example: 0xabc123def456ghi789jkl012mno345pqr678stu901vwx234yz

  • Solana Wallets: Base58 encoded, typically 32-44 characters

    • Example: So11111111111111111111111111111111111111112


Last Updated: January 8, 2026 (Version 1.4.3)

Last updated