Integrate ContextPass in 10 Minutes

Add personalization without profiling to your store

See it working in a live store →

The agent economy is coming.

AI agents are starting to shop, book, and buy for your customers. ContextPass lets your store speak their language — consented, structured context in; personalized, privacy-safe experiences out. Here's the 60-second pitch.

1Sign up and get your keys

Create your merchant account and get your public and secret keys.

Visit the merchant dashboard to sign up. You'll receive two keys:

Save your secret key immediately. It's shown only once during signup. If you lose it, you'll need to rotate your keys.

2Drop in the script tag

Add this script tag to your store's page:

<script src="https://contextpass.io/sdk/contextpass.js"></script>

Then initialize the SDK with your public key:

<script>
ContextPass.init({
  publicKey: 'cp_pk_your_key_here'
});
</script>

3Request fields when you need them

Call requestFields() when you want the user's context. For example, on page load or when they click "Personalize":

<button id="personalizeBtn">Get Personalized Recommendations</button>

<script>
document.getElementById('personalizeBtn').addEventListener('click', async () => {
  const result = await ContextPass.requestFields(
    ['size', 'budget'],
    {
      purpose: 'Find items in your size and price range',
      retention: 'temporary'  // or 'permanent'
    }
  );

  if (result.approved) {
    console.log('Grant created:', result.grantId);
    // Send grantId to your backend
    await fetch('/api/personalize', {
      method: 'POST',
      body: JSON.stringify({ grantId: result.grantId })
    });
  } else {
    console.log('User denied:', result.reason);
  }
});
</script>
What's a grant? A grant is a temporary authorization to access specific fields. The user controls it—they can see and revoke it anytime.

4Exchange grants server-side

Your backend receives the grantId and exchanges it for the actual field values using your secret key:

// Node.js example
const response = await fetch('https://api.contextpass.io/v1/tokens/exchange', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer cp_sk_your_secret_key',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ grant_id: grantId })
});

const { fields } = await response.json();
console.log(fields); // { size: 'M', budget: '500' }
Never expose your secret key in browsers. Always exchange grants server-side.

Webhook Events

When important events happen, ContextPass sends webhooks to your endpoint. (Coming in v0.2)

Event Payload When
cp:fields-approved { grantId, pairwiseId, fields } User approved field request
cp:fields-denied { fields, reason } User denied field request
cp:grant-revoked { grantId } User revoked a grant
cp:token-exchanged { grantId, pairwiseId } Your backend exchanged a grant

Smart Re-rank — your catalog, personalized

Don't write your own ranking logic. Send us your catalog + the user's grant_id, we send back the catalog re-ranked with reasons. Two modes:

Live demo · production API
Click a button, watch our gateway re-rank a real catalog in milliseconds.
Try it now →
Heuristic · included on every tier
Free per call · sub-10ms

Pure attribute matching: size, shoe_size, budget, style, activities, colors. Returns a score and a list of reasons per item. Good for 80% of merchants.

AI · Pro tier ($299/mo)
GPT-4o-mini · ~1–2s

We pre-filter to the top 50 candidates, then GPT re-ranks with natural-language reasoning. Better for nuanced catalogs (apparel, beauty, gear). Aggressive caching keeps cost down.

10-line integration (server-side)

// You already have grant_id from ContextPass.requestFields()
// Send your catalog + grant_id, get back ranked products.
const r = await fetch('https://api.contextpass.io/v1/rank', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer cp_sk_YOUR_SECRET_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    grant_id: req.body.grant_id,
    catalog:  await loadProducts(),  // array of { id, name, price, ... }
    mode:     'heuristic'            // or 'ai' if you're on Pro
  })
});
const { ranked } = await r.json();
// ranked = [{ id, score, reasons: [{ label, value }] }, ...]
// Sort your catalog by ranked order and render.

cURL

curl -X POST https://api.contextpass.io/v1/rank \
  -H "Authorization: Bearer cp_sk_YOUR_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "grant_id": "grt_abc123",
    "catalog": [
      { "id": "sku-1", "name": "Trail Runner v3", "price": 145, "style": "athletic", "activities": ["running","hiking"] },
      { "id": "sku-2", "name": "Court Shoe", "price": 89, "style": "minimalist" }
    ],
    "mode": "heuristic"
  }'

Response shape

{
  "ranked": [
    {
      "id": "sku-1",
      "score": 7,
      "reasons": [
        { "label": "Style", "value": "athletic" },
        { "label": "Activities", "value": "running, hiking" },
        { "label": "Budget", "value": "$145 fits $150–$300" }
      ]
    },
    { "id": "sku-2", "score": 2, "reasons": [...] }
  ],
  "mode": "heuristic",
  "cached": false,
  "took_ms": 8
}

Real example — same input, both modes

Below is an actual production response from api.contextpass.io/v1/rank. The shopper's grant carries { size: "M", shoe_size: "US 10", budget: "$150–$300", style: "athletic, minimalist", activities: "running, hiking" } and the catalog is five sneakers/boots:

Catalog sent
a · Trail Runner v3 · $145 · athletic · running, hiking
b · Court Sneaker · $89 · minimalist
c · Leather Boot · $320 · classic
d · Basketball Shoe · $120 · athletic · basketball
e · Hiking Boot · $210 · outdoor · hiking
mode: "ai" · Pro tier · took_ms: 6460 (cold), 399 (cached)
{
  "ranked": [
    {
      "id": "a",
      "score": 1,
      "reasons": [{
        "label": "AI",
        "value": "Perfect match for size, style,
                  activities, and budget."
      }]
    },
    {
      "id": "e",
      "score": 0.8,
      "reasons": [{
        "label": "AI",
        "value": "Fits size and activities,
                  within budget but different style."
      }]
    }
  ],
  "mode": "ai",
  "cached": false,
  "took_ms": 6460
}

AI returns only the items that genuinely fit, with natural-language reasoning per pick. Court Sneaker, Leather Boot, and Basketball Shoe are filtered out entirely (model decided they don't match the shopper's activities or budget).

mode: "heuristic" · Every tier · took_ms: ~10–400
{
  "ranked": [
    { "id": "a", "score": 8, "reasons": [
      { "label": "Budget", "value": "$145 fits $150–$300" },
      { "label": "Style", "value": "athletic" },
      { "label": "Activities", "value": "running, hiking" }
    ]},
    { "id": "b", "score": 4, "reasons": [
      { "label": "Budget", "value": "$89 fits $150–$300" },
      { "label": "Style", "value": "minimalist" }
    ]},
    { "id": "d", "score": 4, "reasons": [
      { "label": "Budget", "value": "$120 fits $150–$300" },
      { "label": "Style", "value": "athletic" }
    ]},
    { "id": "e", "score": 4, "reasons": [
      { "label": "Budget", "value": "$210 fits $150–$300" },
      { "label": "Activities", "value": "hiking" }
    ]},
    { "id": "c", "score": 0, "reasons": [] }
  ],
  "mode": "heuristic",
  "cached": false,
  "took_ms": 416
}

Heuristic returns every item with a structured score and per-field reasons. You sort by score and decide your own cutoff. Sub-10ms warm.

Cache behavior in production: the AI call took 6.4s on its first invocation (cold worker + cold OpenAI connection). The second call with the same input came back in 399ms with "cached": true. Heuristic's first-call cold time was 416ms — warm calls drop to under 50ms.

Notes

API Reference

POST /v1/merchants

Sign up a new merchant (you do this via the dashboard).

POST /v1/grants

Browser SDK: Create a grant after user approves consent.

Auth: Authorization: Bearer cp_pk_*

POST /v1/grants/:id/revoke

Revoke a grant (can use public or secret key).

POST /v1/tokens/exchange

Server-side: Exchange grant for field values.

Auth: Authorization: Bearer cp_sk_* (secret key only)

POST /v1/rank

Server-side: Re-rank a catalog against the user's preferences. Heuristic mode on every tier; AI mode on Pro+.

Auth: Authorization: Bearer cp_sk_* (secret key only)

POST /v1/alerts

Server-side: Push a Drops feed alert to a user's wallet (sale, restock, new version, etc.).

Auth: Authorization: Bearer cp_sk_*

Getting Help