How Veil works
Veil is the system of record for who paid for what. Your site decides what renders. Readers pay once and unlock in place; the money settles into your own connected payment account.
1 · Connect your payment provider
Onboard through Stripe Connect in a couple of minutes. You stay the merchant of record on your own account. Veil never holds your funds, it just orchestrates checkout and takes a platform fee.
2 · Mark what’s paywalled
Give each piece of content an identifier and a price. Veil tracks entitlements against a user identifier you supply, or the email captured at checkout, so there are no reader accounts to manage.
3 · Gate the content
Two ways, one entitlement record. Embed the widget for an instant preview paywall, or check entitlements on your server so premium content is never rendered unpaid. Serious setups run both.
4 · Reader unlocks in place
After a one-time payment, the reader is redirected back and the content unlocks. No login, no subscription. The entitlement persists so they’re never asked to pay twice.
Gate it your way
Both paths share the same entitlement record. Start with one, add the other when you need it.
Start in an afternoon: the widget
One element, one script: a polished preview paywall with hosted checkout, rendered in a shadow DOM so it never clashes with your styles. It is the fastest path to your first payment and the base layer for the CMS plugins on the way.
<div data-veil></div>
<script src="https://api.veil.ninja/widget.js"></script>
<script>
Veil.init({
apiUrl: 'https://api.veil.ninja',
publisherKey: 'veil_live_XXXXXXXX', // your public widget key prefix
contentId: 'my-article-slug',
});
</script>Enforce on your server: the hard gate
Check the entitlement server-side before you render. Signed entitlement cookies let your SSR layer skip the per-render API call, and the SDK is zero-dependency and edge-portable (Node, Vercel Edge, Cloudflare Workers).
import { Veil } from '@veil/sdk';
const veil = new Veil({ apiKey: process.env.VEIL_API_KEY });
const { entitled } = await veil.entitlements.check({
contentId: 'my-article-slug',
userIdentifier: userId,
});
if (!entitled) return preview;
// Premium content never leaves your server unpaid.The server-side entitlement API is live today; @veil/sdk lands on npm soon, with guides for Next.js, Payload, Strapi and Sanity.
Honest by design: visibility vs. delivery
The widget checks entitlement in the browser and reveals content on the page. It gatesvisibility, which is perfect for previews and quick starts. The server-side check gates delivery: premium content never reaches a browser that hasn’t paid. Serious publishers run both: the widget for the purchase experience, the server check for enforcement.