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:
cp_pk_*— Public key (safe to use in browsers)cp_sk_*— Secret key (keep this private, server-side only)
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>
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' }
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:
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.
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:
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
{
"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).
{
"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
- Catalog limit: 5,000 items per call. Chunk for larger catalogs, or contact us about Scale tier.
- Caching: keyed by
(grant_id, catalog_hash, mode). Heuristic 5min TTL, AI 1hr. Passcache_bust:trueto skip. - If
mode=aifails (model error, etc.) we automatically fall back to heuristic. Responsemodefield tells you which one ran. - Pro-tier check is on
mode=aionly. Starter merchants callingmode=aiget a 403 with an upgrade pointer;mode=heuristicworks on every tier.
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
- Check the SDK docs
- Request source access by email: [email protected]
- Email: [email protected]