> ## Documentation Index
> Fetch the complete documentation index at: https://podium.build/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Usage Examples

> Complete workflow examples with the Podium SDK — products, orders, campaigns, companion agents, tasks, rewards, and agentic commerce

These examples use the [Podium TypeScript SDK](/docs/sdk/setup). Each section is a self-contained workflow you can adapt for your application.

```typescript theme={null}
import { createPodiumClient, ApiError } from '@podium-sdk/node-sdk'

const client = createPodiumClient({
  apiKey: process.env.PODIUM_API_KEY
})
```

## Product Catalog Management

### Create, Configure, and Publish a Product

```typescript theme={null}
const product = await client.merchantProducts.create({
  creatorId: 'creator_abc',
  requestBody: {
    name: 'Organic Face Serum',
    slug: 'organic-face-serum',
    description: 'Lightweight hydrating serum with hyaluronic acid and vitamin C',
    price: 2500,
    maxDiscount: 500,
    allowedPointSources: null,
    media: [
      { url: 'https://cdn.example.com/serum-hero.jpg', type: 'IMAGE', order: 0 },
      { url: 'https://cdn.example.com/serum-texture.jpg', type: 'IMAGE', order: 1 },
    ],
  },
})

await client.merchantProducts.updateByProductId({
  creatorId: 'creator_abc',
  productId: product.id,
  requestBody: {
    supply: 200,
    pointEligibility: 'ELIGIBLE',
    shippingType: 'STANDARD',
    attributes: [
      {
        name: 'Size',
        type: 'VARIANT',
        variants: [
          { value: '30ml', price: 2500, supply: 100, order: 0 },
          { value: '50ml', price: 3500, supply: 60, order: 1 },
          { value: '100ml', price: 5000, supply: 40, order: 2 },
        ],
      },
    ],
  },
})

await client.merchantProducts.publish({
  creatorId: 'creator_abc',
  productId: product.id,
  requestBody: { userId: 'admin_user_id' },
})
```

### List and Filter Products

```typescript theme={null}
const published = await client.product.list({
  categories: '1,2,3',
  page: 1,
  limit: 20,
})

const creatorProducts = await client.merchantProducts.list({
  creatorId: 'creator_abc',
  status: 'PUBLISHED',
})
```

***

## Order and Checkout Workflows

### Stripe Checkout (Consumer App)

```typescript theme={null}
const order = await client.userOrders.create({
  id: userId,
  requestBody: { productId: 'clx9prod001', quantity: 1 },
})

await client.userOrderProducts.createByProductId({
  id: userId,
  orderId: order.id,
  productId: 'clx9prod001',
  requestBody: { quantity: 1, variantIds: ['clx9var_30ml'] },
})

const shippingQuote = await client.order.createShippingQuote({
  id: order.id,
  requestBody: {
    firstName: 'Jane',
    lastName: 'Doe',
    address: {
      line1: '123 Main St',
      line2: null,
      city: 'San Francisco',
      state: 'CA',
      postalCode: '94102',
      countryCode: 'US',
    },
  },
})

const checkout = await client.userOrder.checkout({
  id: userId,
  orderId: order.id,
  requestBody: { points: 500 },
})
// checkout contains Stripe PaymentIntent clientSecret

// After Stripe webhook confirms payment:
await client.userOrderPoints.replaceFinalize({
  id: userId,
  orderId: order.id,
})
```

### x402 Checkout (Agent)

The x402 payment flow uses HTTP directly — it negotiates USDC payment via response headers:

```typescript theme={null}
const response = await fetch(
  `https://api.podium.build/api/v1/x402/order/${orderId}/pay`,
  { method: 'POST' }
)

if (response.status === 402) {
  const requirements = response.headers.get('X-PAYMENT-REQUIREMENTS')
  const parsed = JSON.parse(atob(requirements!))

  const paymentPayload = await signUsdcTransfer({
    to: parsed.payTo,
    amount: parsed.maxAmountRequired,
    network: 'base',
  })

  const receipt = await fetch(
    `https://api.podium.build/api/v1/x402/order/${orderId}/pay`,
    {
      method: 'POST',
      headers: { 'X-PAYMENT': btoa(JSON.stringify(paymentPayload)) },
    }
  )
}
```

Or use the SDK for the final settlement after signing the payment:

```typescript theme={null}
await client.x402.createOrderPay({ id: orderId })
```

### Buy Now (Single-Step Purchase)

```typescript theme={null}
const result = await client.product.buyNow({
  id: 'clx9prod001',
  requestBody: {
    quantity: 1,
    variantIds: ['clx9var_30ml'],
    shouldUseStripe: true,
  },
})
```

### Guest Checkout

```typescript theme={null}
const guestOrder = await client.guests.createOrder({
  requestBody: { productId: 'clx9prod001', quantity: 1 },
})

await client.guests.createOrderProductByProductId({
  id: guestOrder.id,
  productId: 'clx9prod001',
  requestBody: { quantity: 1 },
})

const checkout = await client.guests.checkout({ id: guestOrder.id })
```

***

## Campaign Workflows

### Create and Run a Swipe Campaign

```typescript theme={null}
const campaign = await client.campaigns.create({
  requestBody: {
    creatorId: 'creator_abc',
    type: 'SWIPE',
  },
})

await client.campaigns.replace({
  id: campaign.id,
  requestBody: {
    title: 'What moisturizer matches your skin?',
    description: 'Swipe right on your favorites',
    startDate: new Date().toISOString(),
    endDate: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(),
  },
})

await client.campaigns.updateSubmit({ id: campaign.id })
await client.campaigns.publish({
  id: campaign.id,
  requestBody: { requiresReview: false },
})

await client.campaigns.vote({
  id: campaign.id,
  requestBody: {
    userId: 'user_123',
    votes: [{ attributeId: 1, optionId: 2 }],
  },
})

const analytics = await client.campaigns.getAnalytics({ id: campaign.id })
```

### Run a Survey Campaign

```typescript theme={null}
const survey = await client.campaigns.create({
  requestBody: {
    creatorId: 'creator_abc',
    type: 'SURVEY',
  },
})

await client.campaigns.createSurvey({
  id: survey.id,
  requestBody: {
    userId: 'user_456',
    responses: [
      { questionId: 1, answer: 'Oily skin' },
      { questionId: 2, answer: ['Hydration', 'SPF'] },
    ],
  },
})

const report = await client.campaigns.getSurveyReport({ id: survey.id })
```

***

## Companion Agent Workflows

### Full Agent Lifecycle

```typescript theme={null}
const user = await client.user.create({
  requestBody: {
    email: 'shopper@example.com',
    privyId: 'did:privy:abc123',
  },
})

const { data: profile } = await client.companion.createProfile({
  userId: user.id,
  requestBody: {
    skinType: 'Oily',
    concerns: ['Acne', 'SPF protection'],
    priceRange: { min: 15, max: 50 },
    brands: ['CeraVe', 'The Ordinary'],
    avoidances: ['fragrance', 'alcohol'],
  },
})

const { data: recs } = await client.companion.listRecommendations({
  userId: user.id,
})

await client.companion.createInteractions({
  requestBody: {
    userId: user.id,
    productId: recs[0].id,
    action: 'RANK_UP',
  },
})

const { data: order } = await client.companion.createOrders({
  requestBody: {
    userId: user.id,
    productId: recs[0].id,
    shippingAddress: { street: '123 Main St', city: 'San Francisco', state: 'CA', zip: '94102' },
    email: 'shopper@example.com',
  },
})

await client.companion.createProfilePoints({
  userId: user.id,
  requestBody: {
    amount: 25,
    details: { reason: 'order_placed', orderId: order.id },
  },
})
```

***

## Points and Loyalty

### Earn and Spend Points

```typescript theme={null}
await client.user.createPoints({
  id: userId,
  requestBody: {
    amount: 50,
    creatorId: 'creator_abc',
    details: { source: 'campaign_completion', campaignId: 'campaign_abc' },
  },
})

const balance = await client.user.getPoints({ id: userId })

const history = await client.user.getPointsHistory({
  id: userId,
  page: 1,
  limit: 20,
  order: 'desc',
})

// Apply points to an order, then finalize after payment
await client.userOrder.checkout({
  id: userId,
  orderId: orderId,
  requestBody: { points: 200 },
})

// After payment succeeds:
await client.userOrderPoints.replaceFinalize({ id: userId, orderId })

// If payment fails, revert the points hold:
await client.userOrderPoints.revert({ id: userId, orderId })
```

***

## Task Pool (On-Chain Bounties)

### Create a Task

```typescript theme={null}
const { data: task } = await client.tasks.createTask({
  requestBody: {
    merchantAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18',
    amountUSDC: 5.0,
    acceptanceCriteria: 'Write a 200+ word product review with personal experience, star rating 1-5, and photo',
    verificationMethod: 'Oracle',
    durationSeconds: 86400,
    campaignId: 'campaign_abc',
  },
})
```

### Solver Workflow (HTTP)

```typescript theme={null}
const BASE = 'https://api.podium.build/api/v1'
const headers = {
  'Authorization': `Bearer ${process.env.PODIUM_API_KEY}`,
  'Content-Type': 'application/json',
}

const solver = await fetch(`${BASE}/solver/register`, {
  method: 'POST',
  headers,
  body: JSON.stringify({ walletAddress: '0xSolverAddress...' }),
}).then(r => r.json())

const tasks = await fetch(`${BASE}/solver/tasks`, { headers }).then(r => r.json())

await fetch(`${BASE}/solver/tasks/${taskId}/claim`, {
  method: 'POST',
  headers,
})

await fetch(`${BASE}/solver/tasks/${taskId}/submit`, {
  method: 'POST',
  headers,
  body: JSON.stringify({
    proof: 'https://example.com/review-link',
    metadata: { wordCount: 342, rating: 4 },
  }),
})
```

***

## On-Chain Rewards

### Create and Manage Reward Programs

```typescript theme={null}
const reward = await client.nftRewards.createNftReward({
  requestBody: {
    type: 'FREE_PRODUCT',
    creatorId: 'creator_abc',
  },
})

await client.nftRewards.replace({
  id: reward.id,
  requestBody: {
    name: 'Free Serum Reward',
    description: 'Redeem for a free Organic Face Serum',
    imageUrl: 'https://cdn.example.com/reward.png',
    points: 500,
  },
})

await client.nftRewards.publish({ id: reward.id })

// Grant a reward to a user
await client.nftRewards.createNftRewardGrant({
  id: reward.id,
  requestBody: {
    userId: 'user_123',
    creatorId: 'creator_abc',
  },
})
```

### Check and Redeem User Rewards

```typescript theme={null}
const earned = await client.userNfTs.listEarned({ id: userId })
const redeemable = await client.userNfTs.listRedeemable({ id: userId })

await client.userNfTs.redeem({
  id: userId,
  network: 'base',
  address: '0xNftContract...',
  tokenId: '42',
})

const status = await client.userNfTs.getStatus({
  id: userId,
  network: 'base',
  address: '0xNftContract...',
  tokenId: '42',
})
```

### Reward Types

| Type               | Description                   |
| ------------------ | ----------------------------- |
| `FREE_PRODUCT`     | Redeem for a free product     |
| `DISCOUNT_CODE`    | Percentage or fixed discount  |
| `EVENT_PASS`       | Access pass for events        |
| `POINTS`           | Bonus point grant             |
| `EXCLUSIVE_ACCESS` | Gated content or early access |
| `CUSTOM_REWARD`    | Custom reward type            |

***

## Agentic Commerce (Public Endpoints)

### Query the Agentic Product Feed

No API key required — designed for machine consumption:

```typescript theme={null}
const feed = await client.agentic.listProductsFeed({
  page: 1,
  limit: 20,
  categories: '1,2,3',
})
```

Or via HTTP with intent context headers:

```typescript theme={null}
const response = await fetch(
  'https://api.podium.build/api/v1/agentic/products/feed?page=1&limit=20',
  {
    headers: {
      'X-INTENT-CONTEXT': JSON.stringify({
        concerns: ['hydration'],
        priceRange: { min: 10, max: 50 },
      }),
    },
  }
)
const products = await response.json()
```

### Create an Agentic Checkout Session

```typescript theme={null}
const session = await client.agentic.createCheckoutSessions({
  requestBody: {
    items: [{ id: 'clx9prod001', quantity: 1 }],
    shippingAddress: {
      firstName: 'Jane',
      lastName: 'Doe',
      address: {
        line1: '123 Main St',
        line2: null,
        city: 'San Francisco',
        state: 'CA',
        postalCode: '94102',
        countryCode: 'US',
      },
    },
  },
})

// Update the session with email
const updated = await client.agentic.updateCheckoutSessions({
  id: session.id,
  requestBody: { email: 'customer@example.com' },
})

// Check session state
const state = await client.agentic.getCheckoutSessions({ id: session.id })
```

***

## Shopify Integration

### List and Sync Shopify Products

```typescript theme={null}
const available = await client.shopify.getProductsAvailableByCreatorId({
  creatorId: 'creator_abc',
})

await client.shopify.sync({
  creatorId: 'creator_abc',
  requestBody: { productIds: ['shopify_prod_1', 'shopify_prod_2'] },
})

const shop = await client.shopify.getShopByCreatorId({
  creatorId: 'creator_abc',
})
```

***

## Error Handling

All SDK methods throw `ApiError` with structured error details:

```typescript theme={null}
import { createPodiumClient, ApiError } from '@podium-sdk/node-sdk'

const client = createPodiumClient({ apiKey: process.env.PODIUM_API_KEY })

try {
  const products = await client.product.list({ page: 1 })
} catch (error) {
  if (error instanceof ApiError) {
    console.error(`${error.status} ${error.statusText}: ${error.message}`)
    console.error('URL:', error.url)
    console.error('Body:', error.body)
  }
}
```

Common error codes:

| Status | Meaning                                    |
| ------ | ------------------------------------------ |
| `400`  | Validation error (check request body)      |
| `401`  | Missing or invalid API key                 |
| `403`  | Insufficient permissions for this resource |
| `404`  | Resource not found                         |
| `409`  | Conflict (e.g., duplicate slug)            |
| `429`  | Rate limit exceeded                        |
