Pixels
The pixels namespace stores a merchant's analytics tracking config — Meta pixel + Conversions API access token, TikTok pixel, Google Analytics ID, Google Ads conversion ID and purchase label — and exposes a redacted public read so storefronts can fire client-side events without ever seeing the CAPI secret. This page covers ripllo.pixels on the Node SDK. For the HTTP surface, see API → Pixels.
Namespace
ripllo.pixels.get()
ripllo.pixels.update(input)
ripllo.pixels.public(accountId)
The first two are merchant-authenticated CRUD; the third is anonymous and used by the storefront <head> injector to learn which pixels to mount. The split is the entire reason this resource exists — one shape with secrets for the dashboard, a slim shape without secrets for the public.
Methods
pixels.get
Signature. ripllo.pixels.get(): Promise<MerchantPixels>
Returns the full pixel config for the calling workspace, including the Meta CAPI access token. Use this in the dashboard's pixel-settings page. A merchant who has never saved a config gets an all-null stub with enabled: true rather than null.
const pixels = await ripllo.pixels.get();
console.log(pixels.metaPixelId, pixels.metaCapiAccessToken ? '(set)' : '(unset)');
pixels.update
Signature. ripllo.pixels.update(input): Promise<MerchantPixels>
PATCH semantics — pass only the fields you want to set. Pass null to clear a field; passing undefined (the default for absent keys in a partial object) leaves it untouched. Upserts, so the first call creates the row.
await ripllo.pixels.update({
metaPixelId: '1234567890',
metaCapiAccessToken: 'EAAGm0PX...',
metaTestEventCode: 'TEST12345',
googleAnalyticsId: 'G-ABCD1234',
googleAdsConversionId: 'AW-1234567890',
googleAdsPurchaseLabel: 'abcDEF123ghi',
tiktokPixelId: 'C8R12345...',
enabled: true,
});
// Clear a pixel:
await ripllo.pixels.update({ tiktokPixelId: null });
Unknown keys are dropped silently. The PATCH body is zod-parsed and only recognised keys reach the database, so
update({ metaCapiToken: '…', ga4MeasurementId: '…' })returns200 OKhaving stored nothing. Those names do not exist — usemetaCapiAccessTokenandgoogleAnalyticsId. There is noga4ApiSecretand notiktokAccessTokenfield at all: Ripllo stores no GA4 Measurement Protocol secret and no TikTok Events API token.
pixels.public
Signature. ripllo.pixels.public(accountId): Promise<PublicPixels | null>
Anonymous read — returns the merchant's pixel IDs without any server-side secrets. Storlaunch's storefront calls this at SSR time to know which <script> tags to inject; the Meta CAPI server-side flow never ships through this surface.
const ids = await ripllo.pixels.public('acc_<merchant>');
if (ids?.metaPixelId) injectMetaPixel(ids.metaPixelId);
if (ids?.googleAnalyticsId) injectGa4(ids.googleAnalyticsId);
Returns null in three cases: the merchant has never set up pixels, the config exists but enabled is false, or every ID on it is empty. So a null here is not proof the workspace is missing — it can equally mean "tracking is switched off". Just check the response.
Types
interface MerchantPixels {
id?: string;
accountId?: string;
metaPixelId: string | null;
metaCapiAccessToken?: string | null; // server-only; never on PublicPixels
metaTestEventCode?: string | null; // for Meta's Test Events tab
googleAnalyticsId: string | null;
googleAdsConversionId: string | null;
googleAdsPurchaseLabel: string | null;
tiktokPixelId: string | null;
enabled: boolean;
}
interface PublicPixels {
metaPixelId: string | null;
googleAnalyticsId: string | null;
googleAdsConversionId: string | null;
googleAdsPurchaseLabel: string | null;
tiktokPixelId: string | null;
enabled: boolean;
}
PublicPixels carries no accountId — you already know which workspace you asked for. The Node SDK's update accepts Partial<MerchantPixels>, so every field above (including metaCapiAccessToken) is settable through that method; only the public read strips the secret.
Common patterns
SSR storefront injection
// In Storlaunch's `/s/:merchant` route handler:
const pixels = await ripllo.pixels.public(merchant.accountId);
return renderHead({
metaPixel: pixels?.metaPixelId,
ga4: pixels?.googleAnalyticsId,
tiktok: pixels?.tiktokPixelId,
});
Cache the public response — pixel IDs change rarely and the call is on the hot path for every storefront pageview.
Server-side Meta CAPI event
The CAPI flow lives on your backend, not in Ripllo — Ripllo only stores the credentials. Pull them at request time, build the event, and ship it to Meta:
async function sendCapiPurchase(orderId: string) {
const pixels = await ripllo.pixels.get(); // merchant key — has secrets
if (!pixels.metaPixelId || !pixels.metaCapiAccessToken) return;
await fetch(`https://graph.facebook.com/v18.0/${pixels.metaPixelId}/events`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
data: [{ event_name: 'Purchase', event_time: Date.now() / 1000, /* ... */ }],
access_token: pixels.metaCapiAccessToken,
test_event_code: pixels.metaTestEventCode ?? undefined,
}),
});
}
Don't proxy this through Ripllo — latency and rate-limit budgets belong to your service, not ours.
Migrate from inline pixel IDs to Ripllo
If you used to store pixel IDs directly in your product's DB, the migration is one update call per merchant:
for (const m of merchants) {
await ripllo.pixels.update.bind(ripllo.forMerchant(m.accountId).pixels)({
metaPixelId: m.legacy.fbPixel,
googleAnalyticsId: m.legacy.ga4,
googleAdsConversionId: m.legacy.googleAds,
});
}
(forMerchant returns a client clone scoped to a specific workspace — only valid with a platform-admin key.)
Errors
| Code | Status | Cause |
|---|---|---|
VALIDATION |
400 | An unrecognised type, or an ID over its length cap (64 chars, except metaCapiAccessToken at 500). Format is not checked — a non-numeric Meta pixel ID is stored as given. |
NO_ACCOUNT |
403 | The principal carries no accountId. |
INSUFFICIENT_SCOPE |
403 | API key lacks read (for GET /pixels) or write (for the PATCH). ripllo:platform:admin is a superset of both. |
public(accountId) does not 404 for an unknown workspace — it answers 200 with data: null, the same as a disabled or empty config.
See Errors for the full handling guide.
Next
- Feeds — the Google Merchant Center XML feed.
- API → Pixels — HTTP-level reference.