Quickstart
From zero to your first query. This guide walks you through connecting to the Cresva Storefront API using the Agent Commerce Protocol.
@cresva/sdkandcresvapackages described below describe the planned client surface and ship with v0.1.0. Install lines will work once packages are published. Today, every example also includes a copy-pasteable cURL command that hits the live API directly.Try it now (no key required)
The discovery endpoint is unauthenticated. Run this and confirm you get a JSON manifest back before going further.
curl https://api.cresva.ai/.well-known/acp.jsonPrerequisites
Before you begin, make sure you have the following installed and ready:
- RequiredNode.js 18+ or Python 3.9+ — the Cresva SDK requires a modern runtime. Run
node -vorpython3 --versionto check. - RequiredA Cresva account — sign up free at cresva.ai/signin. No credit card required for sandbox access.
- RequiredA product catalog — at least one product uploaded to your Cresva dashboard. You can use our sample catalog if you are just testing.
- OptionalA package manager — npm, yarn, or pnpm for JavaScript; pip or poetry for Python.
- OptionalcURL or Postman — useful for testing raw API calls without writing code.
Create your Cresva account
Sign up for a free Cresva account at cresva.ai/signin. You'll get access to the dashboard where you can manage your brand, products, and API keys.
After verifying your email, you will land on the Cresva Dashboard. This is your central hub for managing storefronts, monitoring API usage, viewing analytics, and configuring webhooks. Take a moment to explore the sidebar — you will find sections for Products, Analytics, Settings, and API Keys.
Sandbox vs. Production
Every new account starts in sandbox mode. Sandbox gives you full API access with test data — no real transactions occur. You can switch to production mode from Settings once you are ready to go live.
Connect your product catalog
From the dashboard, connect your product catalog. You can import products via:
- CSV upload - bulk import from a spreadsheet
- Shopify integration - one-click sync from your Shopify store
- API - programmatically push products via the management API
Once connected, Cresva automatically generates an AI-optimized storefront for your products.
The AI-optimized storefront is more than a simple product feed. Cresva processes your catalog to generate rich embeddings, extract structured attributes (like price ranges, categories, and feature lists), and build a semantic index that allows agents to find relevant products through natural language. Far beyond keyword-based search.
What gets indexed?
Cresva indexes product titles, descriptions, images, pricing, availability, reviews, and any custom attributes you provide. The richer your product data, the better the query results. We recommend including at least a title, description, price, and one image per product.
Get your API key
Navigate to Settings → API Keysin the dashboard. You'll see two types of keys:
pk_live_*- Public key for read-only access (product search, browsing)sk_live_*- Secret key for full access (transactions, negotiations)
Copy your public key for this quickstart. You'll also find test keys (pk_test_*) for sandbox testing.
# Add to your .env file
CRESVA_API_KEY=pk_live_your_key_here
CRESVA_BRAND_ID=brand_abc123Environment setup
Create a .env file in your project root to keep credentials out of source code. This file should never be committed to version control.
# Create your project directory
mkdir my-acp-project && cd my-acp-project
# Initialize a new project
npm init -y # JavaScript
# python -m venv .venv && source .venv/bin/activate # Python
# Create environment file
touch .env
# Add .env to .gitignore immediately
echo ".env" >> .gitignoreNow populate your .env file with the keys from your dashboard:
# Cresva API credentials
# Get these from: https://cresva.ai/dashboard/settings/api-keys
# Public key — safe for read-only queries (product search, browsing)
CRESVA_API_KEY=pk_live_your_key_here
# Brand ID — identifies your storefront
CRESVA_BRAND_ID=brand_abc123
# Optional: Use test keys during development
# CRESVA_API_KEY=pk_test_your_test_key_hereNever commit API keys to source control
Always use environment variables or a secrets manager. If you accidentally expose a key, rotate it immediately from the dashboard under Settings → API Keys → Rotate.
Make your first query
Install the SDK and make your first product query.SDK preview
@cresva/sdk and cresva are not yet on npm/PyPI. Use the cURL tab below to call the live API today; the SDK code samples document the planned client surface.
// 1. Install the SDK
// npm install @cresva/sdk
import { CresvaClient } from "@cresva/sdk";
const client = new CresvaClient({
apiKey: process.env.CRESVA_API_KEY,
brandId: process.env.CRESVA_BRAND_ID,
});
// 2. Search for products
const results = await client.query({
intent: "search",
query: "wireless headphones under $200",
filters: {
price: { max: 200, currency: "USD" },
in_stock: true,
},
limit: 5,
});
// 3. Display results
for (const product of results.products) {
console.log(`${product.title} - $${product.price}`);
console.log(` Rating: ${product.reviews_summary?.average}/5`);
console.log(` Trust: ${product.trust_score?.tier}`);
console.log();
}What's happening under the hood
When you call client.query(), the SDK sends a POST request to the Cresva Storefront API. Here is what happens on the server side:
- Authentication — Your API key is validated and rate-limit counters are checked.
- Intent parsing — The
intentfield tells the engine what kind of operation you want."search"triggers a semantic product search. Other intents include"recommend","compare", and"negotiate". - Query embedding — Your natural language query is transformed into a vector embedding and matched against your product catalog's semantic index.
- Filter application — Hard filters like price and stock availability are applied after the semantic match to narrow results.
- Trust scoring — Each result is annotated with a
trust_scorethat reflects product data quality, review authenticity, and brand reliability. - Response assembly — The final response includes matched products, metadata, and pagination tokens if more results are available.
Understanding the response
The query returns a structured response object. Here is what a typical response looks like:
{
"request_id": "req_8f3a2b1c4d5e",
"intent": "search",
"products": [
{
"id": "prod_wireless_001",
"title": "ProSound ANC-400 Wireless Headphones",
"description": "Active noise cancellation with 30-hour battery life.",
"price": 179.99,
"currency": "USD",
"in_stock": true,
"url": "https://store.example.com/products/prosound-anc-400",
"image_url": "https://cdn.cresva.ai/images/prod_wireless_001.jpg",
"reviews_summary": {
"average": 4.6,
"count": 1243
},
"trust_score": {
"tier": "verified",
"score": 0.94,
"factors": ["verified_reviews", "brand_authenticated", "return_policy"]
}
}
],
"total_results": 12,
"has_more": true,
"next_cursor": "cur_abc123def456",
"query_time_ms": 47
}Key fields to note: trust_score.tier can be "verified", "standard", or "unverified". The next_cursor field enables pagination — pass it as the cursor parameter in your next query to fetch additional results.
Set up your storefront for AI agents
To make your storefront discoverable by AI agents, publish an ACP discovery file. Cresva hosts this automatically at:
https://your-domain.com/.well-known/acp.jsonIf you're using a custom domain, add a redirect from /.well-known/acp.json to your Cresva-hosted discovery file. Cresva generates this automatically when you activate your storefront.
The ACP discovery file tells AI agents everything they need to interact with your storefront: which endpoints are available, what capabilities your store supports, and how to authenticate. Here is what the generated file looks like:
{
"acp_version": "2.0",
"brand_id": "brand_abc123",
"storefront_url": "https://api.cresva.ai/api/storefront/brand_abc123",
"capabilities": ["search", "recommend", "compare", "negotiate"],
"authentication": {
"type": "bearer",
"header": "Authorization"
},
"rate_limits": {
"requests_per_minute": 60,
"burst": 10
},
"contact": "support@your-brand.com"
}That's it. Your products are now queryable by any AI agent that speaks ACP.
Security best practices
Protecting your API keys is critical. Follow these guidelines to keep your integration secure.
Never expose secret keys in client-side code
Secret keys (sk_live_*) should only be used in server-side environments. Public keys (pk_live_*) are safe for browser use but only grant read access.
Use environment variables or a secrets manager
Store keys in .env files locally, and use your platform's secrets manager in production (AWS Secrets Manager, Vercel Environment Variables, Doppler, etc.). Never hardcode keys in source files.
Rotate keys regularly
Rotate API keys every 90 days or immediately if you suspect a compromise. The dashboard supports zero-downtime rotation — you can have two active keys simultaneously during the transition period.
Restrict key permissions
Use the most restrictive key type possible. If your integration only needs product search, use a public key. Reserve secret keys for operations that require write access or transaction capabilities.
Add .env to .gitignore
Ensure .env is listed in your .gitignore before your first commit. Use git secret scanning tools to catch accidental commits.
Rate limiting
The Cresva API enforces rate limits to ensure fair usage and system stability. Understanding these limits helps you design resilient integrations.
| Plan | Requests/min | Burst | Daily limit |
|---|---|---|---|
| Sandbox | 30 | 5 | 1,000 |
| Starter | 60 | 10 | 10,000 |
| Growth | 300 | 50 | 100,000 |
| Enterprise | Custom | Custom | Unlimited |
When you hit a rate limit, the API returns a 429 Too Many Requests response with a Retry-After header. The SDK handles retries automatically with exponential backoff, but you can also handle this yourself:
// The SDK retries automatically, but you can configure behavior:
const client = new CresvaClient({
apiKey: process.env.CRESVA_API_KEY,
brandId: process.env.CRESVA_BRAND_ID,
retries: 3, // max retry attempts (default: 3)
retryDelay: 1000, // initial delay in ms (default: 1000)
retryBackoff: "exponential", // "exponential" or "linear"
});
// Or handle rate limits manually:
try {
const results = await client.query({ intent: "search", query: "shoes" });
} catch (err) {
if (err.status === 429) {
const retryAfter = err.headers["retry-after"];
console.log(`Rate limited. Retry after ${retryAfter}s`);
}
}Debugging tips
When things do not work as expected, these techniques will help you diagnose the issue quickly.
Enable verbose logging
Both SDKs support a verbose mode that logs every HTTP request and response. This is invaluable during development.
const client = new CresvaClient({
apiKey: process.env.CRESVA_API_KEY,
brandId: process.env.CRESVA_BRAND_ID,
debug: true, // Logs all HTTP requests and responses
});
// You can also listen for specific events:
client.on("request", (req) => {
console.log(`→ ${req.method} ${req.url}`);
console.log(` Headers: ${JSON.stringify(req.headers)}`);
});
client.on("response", (res) => {
console.log(`← ${res.status} (${res.timing}ms)`);
console.log(` Rate limit remaining: ${res.headers["x-ratelimit-remaining"]}`);
});Inspect the request ID
Every API response includes a request_idfield. When contacting support or reporting issues, always include this ID — it lets the team trace the exact execution path of your request through the system.
Test with the sandbox
Use test keys (pk_test_*) during development. The sandbox environment mirrors production behavior exactly but uses synthetic data and does not count against your production rate limits. Switch between environments by swapping keys — no code changes needed.
Common errors
Here are the most frequent issues developers encounter during setup, along with solutions.
401 Unauthorized: Invalid API key
Double-check that your API key is correctly copied from the dashboard and that you are using the right key type. Public keys start with pk_, secret keys with sk_. Make sure there are no trailing spaces or newlines in your .env file.
403 Forbidden: Brand ID mismatch
The API key you are using does not have access to the specified brand_id. Verify that the CRESVA_BRAND_ID in your .env matches the brand associated with your API key in the dashboard.
404 Not Found: Storefront not activated
Your storefront has not been activated yet. Go to your Cresva dashboard, navigate to Storefront settings, and click Activate. Products must be imported before activation.
422 Unprocessable Entity: Invalid query parameters
Check that your query object matches the expected schema. The "intent" field must be one of: search, recommend, compare, or negotiate. The "limit" must be between 1 and 50.
429 Too Many Requests: Rate limit exceeded
You have exceeded your plan's rate limit. The response includes a Retry-After header indicating how many seconds to wait. The SDK retries automatically, but consider upgrading your plan if you consistently hit limits.
ECONNREFUSED / Network error
The SDK cannot reach the Cresva API. Check your internet connection and verify there are no firewall rules blocking outbound HTTPS traffic to cresva.ai. If you are behind a corporate proxy, configure the SDK's httpAgent option.
TypeError: Cannot read property 'products' of undefined
This usually means the query returned an error that was not caught. Wrap your query call in a try/catch block and inspect the error object for details. Enable debug mode to see the raw response.
Full working example
Here is a complete, runnable script that initializes the client, performs a query, handles errors, and paginates through results. Copy this into a file and run it to verify your setup end to end.
// file: quickstart.mjs
// Run: node quickstart.mjs
//
// Prerequisites:
// npm install @cresva/sdk dotenv
// Create .env with CRESVA_API_KEY and CRESVA_BRAND_ID
import "dotenv/config";
import { CresvaClient } from "@cresva/sdk";
// ── Initialize client ──────────────────────────────────────────
const client = new CresvaClient({
apiKey: process.env.CRESVA_API_KEY,
brandId: process.env.CRESVA_BRAND_ID,
debug: false, // Set to true to see HTTP logs
retries: 3,
});
async function main() {
try {
// ── Step 1: Search for products ────────────────────────────
console.log("Searching for wireless headphones...\n");
const results = await client.query({
intent: "search",
query: "wireless headphones under $200",
filters: {
price: { max: 200, currency: "USD" },
in_stock: true,
},
limit: 5,
});
console.log(`Found ${results.total_results} products (${results.query_time_ms}ms)\n`);
// ── Step 2: Display results ────────────────────────────────
for (const product of results.products) {
console.log(` ${product.title}`);
console.log(` Price: $${product.price} ${product.currency}`);
console.log(` Rating: ${product.reviews_summary?.average ?? "N/A"}/5`);
console.log(` Trust: ${product.trust_score?.tier ?? "unknown"}`);
console.log(` URL: ${product.url}\n`);
}
// ── Step 3: Paginate if more results exist ─────────────────
if (results.has_more) {
console.log("Fetching next page...\n");
const page2 = await client.query({
intent: "search",
query: "wireless headphones under $200",
filters: {
price: { max: 200, currency: "USD" },
in_stock: true,
},
limit: 5,
cursor: results.next_cursor,
});
for (const product of page2.products) {
console.log(` ${product.title} - $${product.price}`);
}
}
// ── Step 4: Get a single product recommendation ────────────
console.log("\nGetting recommendations...\n");
const recs = await client.query({
intent: "recommend",
query: "best noise cancelling headphones for commuting",
limit: 3,
});
for (const product of recs.products) {
console.log(` Recommended: ${product.title} ($${product.price})`);
}
console.log("\nDone! Your Cresva integration is working.");
} catch (err) {
// ── Error handling ─────────────────────────────────────────
if (err.status === 401) {
console.error("Authentication failed. Check your CRESVA_API_KEY.");
} else if (err.status === 429) {
console.error(`Rate limited. Retry after ${err.headers?.["retry-after"]}s`);
} else {
console.error("Unexpected error:", err.message);
if (err.requestId) {
console.error(`Request ID: ${err.requestId} (share this with support)`);
}
}
process.exit(1);
}
}
main();Next steps
Now that you have a working integration, here are the most common paths developers take next.
- API Reference - explore all available endpoints
- Protocol Specification - deep dive into the ACP protocol
- Webhooks Guide - receive real-time event notifications
- SDK Documentation - advanced SDK usage and error handling
- Negotiation API - enable AI agents to negotiate prices and terms on behalf of buyers
- Product Comparison - let agents compare products across multiple attributes side by side
- Analytics Dashboard - monitor which AI agents are querying your storefront and what they are searching for