---
name: keepp-storefront
description: Use when a user wants to build or manage their Keepp storefront — adding, updating, or removing product cards, affiliate items, promo-code deals, or lead-capture cards — through the Keepp Agent API. Requires a Keepp Pro API key (keepp_live_…).
---

# Managing a Keepp Storefront

## What Keepp is

Keepp turns a creator's or small business's social bio link into a **storefront**: a shareable page of product "cards" plus links, built to turn followers into buyers and leads. It's used by sellers, affiliates, coaches, course creators, and link-in-bio creators across Instagram, YouTube, TikTok, Pinterest, and X.

A storefront is made of:
- **Profile** — avatar, display name, short bio
- **Social icons** — links to the owner's social accounts
- **Link blocks** — buttons to a website, booking page, WhatsApp, etc. (plus section headers)
- **Catalog cards** — the shoppable product cards (photo, price, promo code, call-to-action)
- **Mode** — `links only`, `catalog only`, or `links and catalog`

## What this API controls

**This API manages catalog cards (posts) only** — create, list, update, and delete the product cards in the owner's catalog.

You CANNOT change other storefront settings through this API. Social icons, link blocks, the storefront mode, the theme, the hero CTA, and which fields a lead-capture form collects are all set by the owner in the Keepp dashboard. If a user asks for those, tell them to set it under **Storefront → Settings**. Use the rest of this guide as context so you can advise them — but only call the endpoints below.

## Authentication

Every request needs the owner's API key as a bearer token:

```
Authorization: Bearer keepp_live_…
```

Base URL: `https://api.keepp.link`. Keys are generated by a **Pro** account under **AI Agent** in the dashboard. If you don't have one, ask the user for it.

## Endpoints

| Method | Path | Purpose |
|--------|------|---------|
| GET | `/api/v1/posts?cursor=` | List the catalog's cards (paginated). |
| POST | `/api/v1/posts` | Create a card. |
| GET | `/api/v1/posts/:postId` | Fetch one card. |
| PATCH | `/api/v1/posts/:postId` | Update a card. |
| DELETE | `/api/v1/posts/:postId` | Remove a card. |

## The card content model

A card is created/updated with three top-level fields: `imageUrls`, `userContent`, and `cardOverrides`.

```jsonc
{
  "imageUrls": ["https://…/photo.jpg"],   // up to 5; fetched & stored for you. ≤10MB each, JPEG/PNG/WebP/GIF, direct public URL
  "userContent": {
    "name": "Silk scarf",                  // short title (optional)
    "description": "Hand-dyed mulberry silk, 90×90cm.",   // REQUIRED
    "price": "$72",                        // free text — "$72", "From $50", "₹1,499" (optional)
    "promoCode": "SAVE15",                 // promo / referral / discount code (optional)
    "category": "accessories",             // one of the categories below (optional)
    "links": ["https://…"],                // extra links shown on the card (optional)
    "contacts": [{ "type": "whatsapp", "value": "+15551234567" }]   // optional
  },
  "cardOverrides": {                       // how the card behaves (optional; omit to inherit storefront defaults)
    "clickAction": "open_detail",          // "open_detail" | "trigger_cta"
    "ctaType": "link",                     // "message" | "link" | "lead_collection"
    "ctaUrl": "https://shop…/scarf",       // REQUIRED when ctaType = "link"
    "ctaLabel": "Buy now"                  // button text
  }
}
```

`description` is the only required field. Everything else is optional; omitting `cardOverrides` inherits the owner's storefront-wide defaults.

**Categories:** clothing, jewellery, accessories, home_decor, beauty, food_beverage, art, stationery, plants, fitness, travel, real_estate, services, pets, kids_baby, books_media, crafts, other.

**Contact types:** phone, email, whatsapp, telegram, other.

## How a card behaves — two decisions

**1. `clickAction` — what tapping the card does:**
- `open_detail` (default) — opens a full detail view (all photos, full description, price, promo code, CTA button). Use when the buyer needs context before acting.
- `trigger_cta` — tapping fires the CTA immediately, no detail screen. Use for self-explanatory items where you want the least friction.

**2. `ctaType` — what the CTA does:**
- `message` — opens a message to the business. A safe default when there's no checkout link.
- `link` — opens `ctaUrl` (a Shopify/Etsy page, an affiliate link, a booking page, a Google Form). Requires `ctaUrl`. Use when there's a dedicated destination.
- `lead_collection` — opens a short form on the storefront that captures the visitor's contact details and saves them as a lead. Use to capture people who aren't ready to buy (waitlists, sales lists, coaching enquiries). The fields collected are set storefront-wide by the owner — you can't choose them here.

Set `ctaLabel` to match the action: "Buy now", "Order now", "Get the lookbook", "Reserve yours", "Get notified".

## Use-case recipes

**Affiliate / influencer product with a promo code → external link**
```json
{
  "imageUrls": ["https://example.com/serum.jpg"],
  "userContent": { "name": "Vitamin C serum", "description": "My daily glow serum — 15% off with my code.", "price": "$28", "promoCode": "GLOW15", "category": "beauty" },
  "cardOverrides": { "clickAction": "trigger_cta", "ctaType": "link", "ctaUrl": "https://brand.com/serum?ref=me", "ctaLabel": "Shop with my code" }
}
```

**Boutique product sold through your own shop**
```json
{
  "imageUrls": ["https://example.com/scarf.jpg"],
  "userContent": { "name": "Silk scarf", "description": "Hand-dyed mulberry silk, 90×90cm.", "price": "$72", "category": "accessories" },
  "cardOverrides": { "clickAction": "open_detail", "ctaType": "link", "ctaUrl": "https://myshop.com/scarf", "ctaLabel": "Buy now" }
}
```

**Coach / service — capture a lead instead of selling directly**
```json
{
  "imageUrls": ["https://example.com/program.jpg"],
  "userContent": { "name": "1:1 coaching", "description": "6-week program to land your first 5 clients.", "price": "From $400", "category": "services" },
  "cardOverrides": { "clickAction": "trigger_cta", "ctaType": "lead_collection", "ctaLabel": "Apply now" }
}
```

## Responses & errors

Success: `{ "ok": true, "data": { … } }`. Error: `{ "ok": false, "error": { "code": "…", "message": "…" } }`.

- `401 NO_API_TOKEN` / `INVALID_API_TOKEN` — missing or revoked key. Ask the user for a valid key.
- `403 PLAN_REQUIRED` — the account is not on Pro.
- `422 INVALID_IMAGE` — an image URL couldn't be fetched, was the wrong type/size, redirected, or resolved to a non-public address. Use a direct, public `https` image URL.
- `429 RATE_LIMITED` — more than 60 requests per minute. Slow down and retry.

## Guidance

- Confirm with the user before deleting cards.
- Set `price` and `promoCode` whenever you have them — they render on the card and in the detail view and are central to affiliate and sale use cases.
- When bulk-creating, stay under 60 requests per minute.
- Cards publish to the storefront immediately.
- For anything outside catalog cards (links, social icons, mode, theme, lead-capture fields), tell the user to use the Keepp dashboard.

## More context

Keepp's how-to guides explain the storefront in depth:
- Choosing a storefront mode: https://keepp.link/blog/how-to/05-choosing-your-storefront-mode
- How product cards look and behave: https://keepp.link/blog/how-to/06-configuring-how-product-cards-look-and-behave
- Per-post CTAs and custom links: https://keepp.link/blog/how-to/07-setting-per-post-ctas-and-custom-links
