Publisher Integration Guide

Add a Vlexivo Paywall in 10 Minutes

A step-by-step walkthrough from zero to a working HTTP 402 paywall on your Express app. Covers API billing, content paywalls, and AI agent access.

~10 min read
Express.js · Node.js
HTTP 402 Protocol

How Vlexivo Works

Vlexivo uses the standard HTTP 402 "Payment Required" status to protect resources. The flow is three steps:

1
Challenge — your server returns 402

When a consumer hits a paid route without an entitlement token, your middleware calls POST /v1/challenge to get a signed challenge, then returns HTTP 402 with the challenge in the response body.

2
Payment — consumer pays on-chain

The consumer (browser wallet, AI agent, or mobile app) sees the 402, sends crypto to the publisher's settlement wallet, and submits the transaction hash as proof.

3
Unlock — Vlexivo verifies & issues JWT

Vlexivo verifies the on-chain transaction at POST /v1/unlock and returns an entitlement JWT. The consumer re-sends the request with the JWT — your middleware lets them through.


0

Prerequisites

Before you start, make sure you have:

  • Node.js 18+ — Vlexivo requires modern Node.js.
  • A Vlexivo publisher accountRegister here. Free to start, no credit card.
  • Your API key pair — From your dashboard: a vlx_pub_... (publishable, safe for clients) and vlx_sec_... (secret, server-side only).
  • A settlement wallet — Configure your Ethereum/Base or Solana wallet address in Dashboard → Settings. This is where consumer payments land.
  • An existing Express.js app — Or use the minimal skeleton below.
ℹ️

You don't need your own blockchain node. Vlexivo handles on-chain verification against Ethereum mainnet, Base L2, and Solana mainnet on your behalf.


1

Install

Option A — npm package

The official Vlexivo Node.js SDK handles challenge generation and entitlement verification for you:

bash
npm install vlexivo

Option B — Script tag (browser widget)

For content paywalls, embed the Vlexivo widget directly in your HTML. No npm required.

html In your <head>
<script
  src="https://vlexivo.online/sdk/vlx-widget.js"
  data-publisher-id="YOUR_PUBLISHER_ID"
  async
></script>

Option C — Raw HTTP (no SDK)

Vlexivo's protocol is plain HTTP/JSON. You can integrate with any language using fetch or curl. The examples in this guide show both SDK and raw HTTP.

⚠️

Never expose your vlx_sec_... secret key on the client side or in public repos. Use environment variables (process.env.VLEXIVO_SECRET_KEY) for all secret key references.


2

Basic Integration — 5 Minutes

This minimal example protects a single Express route behind a micropayment. Copy-paste, fill in your keys, and you're live.

Step 1 — Create a pricing rule

Before your server can generate challenges, it needs a pricing rule for the resource. Create one via the API (or in your Dashboard → Pricing):

bash Create a pricing rule
curl -X POST https://vlexivo.online/api/pricing \
  -H "X-Api-Key: vlx_sec_YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "scope_type": "per-call",
    "resource_pattern": "/api/premium/data",
    "price_amount": "0.001",
    "price_currency": "USDC"
  }'

The resource_pattern is matched against resource_id values in challenge requests. Use an exact path for per-route pricing, or * for a catch-all.

Step 2 — Add the paywall middleware

Your Express middleware intercepts requests, checks for an entitlement JWT, and returns 402 if none is present:

javascript middleware/paywall.js
const fetch = require('node-fetch'); // or use built-in fetch (Node 18+)

const VLEXIVO_API = 'https://vlexivo.online';
const SECRET_KEY  = process.env.VLEXIVO_SECRET_KEY;  // vlx_sec_...

/**
 * Vlexivo paywall middleware.
 * Protects a route behind a micropayment.
 *
 * Usage:
 *   app.get('/api/premium/data', requirePayment('/api/premium/data'), handler);
 */
function requirePayment(resourceId) {
  return async function vlexivoPaywall(req, res, next) {
    // 1. Check for existing entitlement token
    const token =
      req.headers['x-entitlement'] ||
      (req.headers.authorization || '').replace('Bearer ', '');

    if (token) {
      // 2. Validate the token with Vlexivo
      const validation = await fetch(`${VLEXIVO_API}/api/entitlements/validate`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'X-Api-Key': SECRET_KEY,
        },
        body: JSON.stringify({ token, resource_id: resourceId }),
      }).then(r => r.json());

      if (validation.valid) {
        req.entitlement = validation.entitlement;
        return next(); // ✅ Paid — proceed to route handler
      }
    }

    // 3. No valid token — issue a 402 challenge
    const challengeRes = await fetch(`${VLEXIVO_API}/v1/challenge`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-Api-Key': SECRET_KEY,
      },
      body: JSON.stringify({
        resource_id: resourceId,
        scope_type: 'per-call',
      }),
    });

    const challenge = await challengeRes.json();

    // 4. Return 402 with the challenge — consumer must pay, then retry
    return res.status(402).json({
      error: 'Payment required',
      payment_required: true,
      challenge,
    });
  };
}

module.exports = { requirePayment };

Step 3 — Wire up the route

javascript server.js
const express = require('express');
const { requirePayment } = require('./middleware/paywall');

const app = express();
app.use(express.json());

// ✅ Protected route — requires 0.001 USDC per call
app.get(
  '/api/premium/data',
  requirePayment('/api/premium/data'),
  (req, res) => {
    // Only reached after valid payment
    res.json({
      data: 'Your premium content here',
      paid_by: req.entitlement?.buyer_wallet,
    });
  }
);

app.listen(3000, () => console.log('Server running on :3000'));

Step 4 — Test the flow

bash Verify 402 is returned
# Should return 402 with challenge body
curl -i http://localhost:3000/api/premium/data
bash Access with a valid entitlement token
# After payment, pass the JWT in the Authorization header
curl -i http://localhost:3000/api/premium/data \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

That's the full integration. The three lines that matter: call /v1/challenge, return HTTP 402, validate the JWT on retry. Everything else is ergonomics.


3

Content Paywall Example

Protect a blog post or article behind a micropayment. This example uses scope_type: "per-article" — the reader pays once per article and gets 24-hour access.

Create a per-article pricing rule

bash
curl -X POST https://vlexivo.online/api/pricing \
  -H "X-Api-Key: vlx_sec_YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "scope_type": "per-article",
    "resource_pattern": "*",
    "price_amount": "0.05",
    "price_currency": "USDC",
    "duration_seconds": 86400
  }'

Express route with article paywall

javascript routes/articles.js
const express = require('express');
const fetch = require('node-fetch');
const router = express.Router();

const VLEXIVO_API = 'https://vlexivo.online';
const SECRET_KEY  = process.env.VLEXIVO_SECRET_KEY;

router.get('/articles/:slug', async (req, res) => {
  const { slug } = req.params;
  const resourceId = `/articles/${slug}`;
  const article = await db.getArticle(slug); // your DB call

  if (!article) return res.status(404).json({ error: 'Not found' });

  // --- Check for entitlement token ---
  const token = req.headers['x-entitlement'] ||
    (req.headers.authorization || '').replace('Bearer ', '');

  if (token) {
    const validation = await fetch(`${VLEXIVO_API}/api/entitlements/validate`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', 'X-Api-Key': SECRET_KEY },
      body: JSON.stringify({ token, resource_id: resourceId }),
    }).then(r => r.json());

    if (validation.valid) {
      // Full article — paid access
      return res.json({
        title: article.title,
        content: article.full_content, // complete article body
        paid: true,
      });
    }
  }

  // --- No valid token: return preview + 402 challenge ---
  const challenge = await fetch(`${VLEXIVO_API}/v1/challenge`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', 'X-Api-Key': SECRET_KEY },
    body: JSON.stringify({
      resource_id: resourceId,
      scope_type: 'per-article',
    }),
  }).then(r => r.json());

  return res.status(402).json({
    title: article.title,
    preview: article.excerpt,       // first 200 words shown free
    paid: false,
    payment_required: true,
    challenge,                       // pass to client SDK to trigger payment UI
  });
});

module.exports = router;

Embed the widget in your article template

The Vlexivo widget automatically detects 402 responses and presents the payment UI to the reader:

html article.html
<!-- Embed widget in your article template -->
<script
  src="https://vlexivo.online/sdk/vlx-widget.js"
  data-publisher-id="YOUR_PUBLISHER_ID"
  async
></script>

<!-- Gate the full article body -->
<div data-vlx-gate="article-full">
  <!-- Full content loaded after payment -->
</div>

<!-- Trigger paywall button -->
<button
  data-vlx-price="0.05"
  data-vlx-currency="USDC"
  data-vlx-scope="per-article"
  data-vlx-resource="/articles/my-slug"
>
  Read full article — $0.05
</button>
ℹ️

The widget handles the entire consumer flow: MetaMask/Phantom popup, payment confirmation, and entitlement storage in localStorage. The reader pays once and gets 24 hours of free access on return visits.


4

API Billing Example

Charge per API call — the primary use case for Vlexivo. Every request to your API costs a small amount; the caller pays automatically using their Vlexivo entitlement or agent key.

Full middleware pattern for API billing

javascript middleware/vlexivoMiddleware.js — complete production-ready middleware
const fetch = require('node-fetch');

const VLEXIVO_API = 'https://vlexivo.online';
const SECRET_KEY  = process.env.VLEXIVO_SECRET_KEY;

/**
 * Full Vlexivo API billing middleware.
 *
 * 1. If X-Entitlement or Authorization: Bearer is present, validate it.
 * 2. If valid — pass through (consume 1 entitlement use).
 * 3. If missing or invalid — call POST /v1/challenge, return 402.
 *
 * Consumers use the Vlexivo SDK or agent key to pay automatically.
 */
async function vlexivoBilling(req, res, next) {
  const resourceId = req.path;
  const token =
    req.headers['x-entitlement'] ||
    (req.headers.authorization || '').replace('Bearer ', '').trim();

  if (token) {
    let valid = false;
    try {
      const result = await fetch(`${VLEXIVO_API}/api/entitlements/validate`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'X-Api-Key': SECRET_KEY,
        },
        body: JSON.stringify({ token, resource_id: resourceId }),
      }).then(r => r.json());

      if (result.valid) {
        req.entitlement = result.entitlement;
        valid = true;
      }
    } catch (err) {
      console.error('[Vlexivo] Validation error:', err.message);
    }

    if (valid) return next();
  }

  // No valid entitlement — issue 402 challenge
  try {
    const challengeRes = await fetch(`${VLEXIVO_API}/v1/challenge`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-Api-Key': SECRET_KEY,
      },
      body: JSON.stringify({
        resource_id: resourceId,
        scope_type: 'per-call',
        // Optional: override price inline (no pricing rule needed)
        // price: { amount: '0.001', currency: 'USDC' },
      }),
    });

    const challenge = await challengeRes.json();

    res.setHeader('X-Vlexivo-Challenge-Nonce', challenge.challenge_nonce || '');
    return res.status(402).json({
      error: 'Payment required',
      code:  'PAYMENT_REQUIRED',
      challenge,
      unlock_url: `${VLEXIVO_API}/v1/unlock`,
    });
  } catch (err) {
    console.error('[Vlexivo] Challenge generation failed:', err.message);
    // Fail open — don't block the request if Vlexivo is unreachable
    return next();
  }
}

module.exports = { vlexivoBilling };

Apply to all premium routes

javascript server.js
const express = require('express');
const { vlexivoBilling } = require('./middleware/vlexivoMiddleware');

const app = express();
app.use(express.json());

// Apply billing to all /api/premium/* routes
app.use('/api/premium', vlexivoBilling);

app.get('/api/premium/weather', (req, res) => {
  res.json({ temperature: 72, condition: 'Sunny' });
});

app.get('/api/premium/sentiment', (req, res) => {
  const text = req.query.text || '';
  res.json({ sentiment: 'positive', score: 0.87, text });
});

// Free tier — no billing middleware
app.get('/api/free/ping', (req, res) => {
  res.json({ status: 'ok' });
});

app.listen(3000);

Response format

Your 402 response body should always include the challenge object. This is what SDK consumers and AI agents parse to initiate payment:

json 402 response body
{
  "error": "Payment required",
  "code": "PAYMENT_REQUIRED",
  "challenge": {
    "challenge_nonce": "vlx_nonce_abc123...",
    "publisher_id": 42,
    "resource_id": "/api/premium/weather",
    "scope_type": "per-call",
    "price": { "amount": "0.001", "currency": "USDC" },
    "payment_address": "0xYourSettlementWallet",
    "unlock_url": "https://vlexivo.online/v1/unlock",
    "expires_at": "2026-04-29T12:00:00.000Z",
    "accept_currencies": ["USDC", "ETH", "SOL"]
  },
  "unlock_url": "https://vlexivo.online/v1/unlock"
}
ℹ️

The challenge_nonce is single-use and expires in 5 minutes. If the consumer doesn't pay within that window, they need to request a fresh challenge by hitting your endpoint again.


5

AI Agent Integration

AI agents don't have browser wallets. Vlexivo provides a dedicated machine-to-machine endpoint — POST /v1/agent/pay — that deducts from a prepaid balance and issues an entitlement JWT in a single round-trip.

How agents access paid APIs

1
Agent developer creates an agent key

Via Dashboard → Agent Keys. Fund the key's balance with USDC. Set rate limits and auto-topup threshold.

2
Agent calls POST /v1/agent/pay

One call, no blockchain interaction. Vlexivo deducts the price from the agent's prepaid balance and returns a JWT.

3
Agent uses the JWT to access your API

Passes the entitlement token as Authorization: Bearer <token> or X-Entitlement: <token>. Your existing middleware validates it.

Agent pay — complete code example

javascript agent/vlexivoAgent.js — AI agent accessing a paid API
const fetch = require('node-fetch');

const VLEXIVO_API   = 'https://vlexivo.online';
const AGENT_KEY     = process.env.VLEXIVO_AGENT_KEY;      // vlxa_live_...
const PUBLISHER_KEY = process.env.TARGET_PUBLISHER_KEY;   // Publisher's vlx_sec_...

/**
 * Pay for one API call and get an entitlement JWT.
 * Deducts from prepaid agent balance — no wallet interaction required.
 */
async function payForAccess(resourceId = '*', scopeType = 'per-call') {
  const res = await fetch(`${VLEXIVO_API}/v1/agent/pay`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Agent-Key': AGENT_KEY,
    },
    body: JSON.stringify({
      resource_id: resourceId,
      scope_type: scopeType,
      publisher_api_key: PUBLISHER_KEY,
    }),
  });

  const data = await res.json();

  if (!res.ok || !data.success) {
    if (res.status === 402) {
      throw new Error(`Insufficient balance: $${data.balance_usd} available. Top up at ${data.topup_url}`);
    }
    if (res.status === 429) {
      throw new Error(`Rate limit exceeded. Retry after ${data.retry_after}s`);
    }
    throw new Error(`Payment failed: ${data.error}`);
  }

  return {
    token:        data.entitlement,     // JWT — pass as Authorization: Bearer
    expiresAt:    data.expires_at,
    costUsd:      data.cost_usd,
    balanceCents: data.balance_cents,
  };
}

/**
 * Access a paid API endpoint as an AI agent.
 */
async function callPaidApi(endpoint, resourceId) {
  // 1. Pay first
  const { token, costUsd, balanceCents } = await payForAccess(resourceId);
  console.log(`Paid $${costUsd} | Remaining balance: $${(balanceCents / 100).toFixed(4)}`);

  // 2. Call the API with the entitlement token
  const res = await fetch(endpoint, {
    headers: {
      'Authorization': `Bearer ${token}`,
      // Or: 'X-Entitlement': token
    },
  });

  if (!res.ok) {
    throw new Error(`API call failed: ${res.status} ${await res.text()}`);
  }

  return res.json();
}

// Example usage
(async () => {
  const data = await callPaidApi(
    'https://your-api.example.com/api/premium/weather',
    '/api/premium/weather'
  );
  console.log('Weather data:', data);
})();

Agent pay — response shape

json POST /v1/agent/pay → 200 OK
{
  "success": true,
  "entitlement": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expires_at": "2026-04-29T12:05:00.000Z",
  "cost_micro_usd": 1000,
  "cost_usd": "0.001000",
  "balance_cents": 4999,
  "balance_usd": "49.9900",
  "resource_id": "/api/premium/weather",
  "scope_type": "per-call",
  "latency_ms": 12
}

Check agent balance

bash GET /v1/agent/status — balance & rate limit check (no cost)
curl https://vlexivo.online/v1/agent/status \
  -H "X-Agent-Key: vlxa_live_YOUR_AGENT_KEY"

Rate limits for agents

LimitDefaultConfigurable
Requests per minute60Yes — per agent key
Requests per day10,000Yes — per agent key
Response on exceededHTTP 429 with Retry-After header

6

Testing Without Real Payments

Set DEMO_MODE=true in your environment. In demo mode, Vlexivo's verification engine accepts any well-formed proof without performing on-chain checks. You can test the entire flow locally without spending crypto.

Local .env setup

bash .env (development)
VLEXIVO_SECRET_KEY=vlx_sec_YOUR_SECRET_KEY
VLEXIVO_PUBLISHABLE_KEY=vlx_pub_YOUR_PUBLISHABLE_KEY
DEMO_MODE=true   # <-- skip on-chain verification

Submit a stub proof in demo mode

In demo mode, you can call POST /v1/unlock with a fake transaction hash and it will succeed:

bash Full test flow — challenge → unlock → validate
# 1. Get a challenge
CHALLENGE=$(curl -s -X POST https://vlexivo.online/v1/challenge \
  -H "X-Api-Key: vlx_sec_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"resource_id": "/api/premium/data", "scope_type": "per-call"}')

NONCE=$(echo $CHALLENGE | jq -r '.challenge_nonce')
echo "Nonce: $NONCE"

# 2. Submit a stub proof (demo mode accepts any well-formed proof)
TOKEN=$(curl -s -X POST https://vlexivo.online/v1/unlock \
  -H "Content-Type: application/json" \
  -d "{
    \"proof\": {
      \"tx_hash\": \"0xdeadbeef000000000000000000000000000000000000000000000000deadbeef\",
      \"buyer_wallet\": \"0x1234567890abcdef1234567890abcdef12345678\",
      \"nonce\": \"$NONCE\"
    },
    \"currency\": \"USDC\"
  }" | jq -r '.entitlement_token')

echo "Token: $TOKEN"

# 3. Access the protected route
curl -i http://localhost:3000/api/premium/data \
  -H "Authorization: Bearer $TOKEN"
🚫

Never deploy with DEMO_MODE=true. In demo mode, anyone can unlock any resource with a fake proof. Set DEMO_MODE=false (or remove the env var) before going live.

Unit testing your middleware

javascript tests/paywall.test.js (Jest)
const request = require('supertest');
const nock    = require('nock');
const app     = require('../server');

describe('Vlexivo paywall middleware', () => {
  test('returns 402 when no entitlement token is present', async () => {
    // Mock the Vlexivo challenge endpoint
    nock('https://vlexivo.online')
      .post('/v1/challenge')
      .reply(200, {
        challenge_nonce: 'vlx_nonce_test123',
        price: { amount: '0.001', currency: 'USDC' },
        payment_address: '0xabc',
        unlock_url: 'https://vlexivo.online/v1/unlock',
      });

    const res = await request(app).get('/api/premium/data');
    expect(res.status).toBe(402);
    expect(res.body.challenge).toBeDefined();
    expect(res.body.challenge.challenge_nonce).toBe('vlx_nonce_test123');
  });

  test('passes through with a valid entitlement token', async () => {
    nock('https://vlexivo.online')
      .post('/api/entitlements/validate')
      .reply(200, {
        valid: true,
        entitlement: { buyer_wallet: '0xabc', scope_type: 'per-call' },
      });

    const res = await request(app)
      .get('/api/premium/data')
      .set('X-Entitlement', 'mock-jwt-token');

    expect(res.status).toBe(200);
    expect(res.body.data).toBeDefined();
  });
});

7

Going Live Checklist

Before switching production traffic to your Vlexivo integration, run through this checklist:

  • Remove DEMO_MODE — Unset DEMO_MODE or set to false. On-chain verification is active in production.
  • Set real prices — Review your pricing rules in Dashboard → Pricing. Make sure amounts are correct for your use case ($0.001 is typical for per-call APIs).
  • Configure settlement wallet — Verify your Ethereum/Base or Solana wallet address in Dashboard → Settings. This is where revenue lands.
  • Secret key is in env varsVLEXIVO_SECRET_KEY must never appear in code, git history, or logs.
  • Test with a real micro-payment — Send 0.001 USDC on Base L2 through the actual flow before opening to users.
  • Set up webhooks — Register a payment.completed webhook in Dashboard → Webhooks. Use this for fulfillment, analytics, and anomaly detection.
  • Monitor via analytics — Visit /admin/analytics or Dashboard → Analytics for 7-day event breakdown. Set up alerts for unusual drop-off rates.
  • Handle errors gracefully — Your middleware should fail open (let requests through) if Vlexivo is unreachable, not fail closed. Log the error, don't 500.

Monitoring

Track payment funnel health with these API endpoints:

bash Analytics & monitoring
# 7-day analytics breakdown (challenge, unlock, agent_pay events)
curl https://vlexivo.online/admin/analytics \
  -H "X-Api-Key: vlx_sec_YOUR_KEY"

# Earnings summary (time-windowed)
curl "https://vlexivo.online/api/analytics/earnings?window=7d" \
  -H "X-Api-Key: vlx_sec_YOUR_KEY"

# Recent payments list (with filters)
curl "https://vlexivo.online/api/payments?scope_type=per-call&date_from=2026-04-01" \
  -H "X-Api-Key: vlx_sec_YOUR_KEY"

8

Troubleshooting

Error Code HTTP Cause & Fix
NO_PRICING_RULE 400 No pricing rule matches your resource_id. Create one via POST /api/pricing or pass an inline price in the challenge request.
MISSING_RESOURCE_ID 400 The resource_id field is missing or empty in your challenge request body.
INVALID_PROOF 400 Malformed proof body sent to POST /v1/unlock. Check that tx_hash, buyer_wallet, and nonce are all present and correctly formatted.
NONCE_NOT_FOUND 404 The nonce was never issued or was cleaned up (older than 5 minutes). Request a fresh challenge.
NONCE_REPLAY 409 This nonce has already been used. Each nonce is single-use. Request a new challenge to retry.
CHALLENGE_EXPIRED 410 Challenge expired (5 minute TTL). Request a fresh challenge and submit payment within the window.
Payment verification failed 402 On-chain verification failed. Common causes: tx not confirmed yet (wait 15s, retry), wrong recipient wallet, amount too low. Use DEMO_MODE=true to bypass for testing.
INSUFFICIENT_BALANCE 402 Agent key has insufficient prepaid balance. Top up at Dashboard → Agent Keys or enable auto-topup.
RATE_LIMIT_EXCEEDED 429 Rate limit hit. Check the Retry-After header. Default limits: 60 req/min for /v1/challenge, 30 req/min for /v1/unlock. Contact us for higher limits.
AGE_PROOF_REQUIRED 403 Publisher requires age verification. Consumer must set up an age credential at /consumer/dashboard and include age_proof in the unlock request.

Common integration issues

The payment popup doesn't appear

Ensure your page doesn't block popups. The Vlexivo widget opens in a window.open popup. On iOS Safari, popups are only allowed from direct user gesture handlers. Make sure the payment button click handler calls the SDK synchronously — don't await anything before calling window.open.

Entitlement token expires too fast

Default TTL for per-call is 300 seconds (5 min). For per-article it's 24 hours. Extend via the duration_seconds field on your pricing rule. For sessions, use scope_type: "per-session" and set your own duration.

On-chain verification times out

Vlexivo polls the blockchain for up to 30 seconds after receiving a proof. If the tx confirms after that window, use the retry endpoint:

bash
curl -X POST https://vlexivo.online/v1/unlock/retry \
  -H "Content-Type: application/json" \
  -d '{"nonce": "vlx_nonce_...", "tx_hash": "0x..."}'

Webhook keeps failing

Vlexivo retries with exponential backoff: 1m → 5m → 30m → 2h → 24h. To debug, check Dashboard → Webhooks → Deliveries. Common fixes: return 200 immediately (process async), fix signature verification (X-Vlexivo-Signature header), ensure endpoint is reachable from the internet.

Still stuck?

Email support@vlexivo.online with your publisher ID, the exact endpoint you're calling, and the full error response body. We respond within 24 hours on weekdays.

📖

For full endpoint reference, error codes, and SDK options — see the API Reference →

🚀

Ready to monetize?

Create your free publisher account and add a paywall in minutes. No credit card required.

Create Free Account API Reference