Vagibond
Vagibond

Follow Vagibond

Stay connected with us on social media for updates on new ventures.

Thanks for subscribing!

Solicit API

Embeddable service configurator with plans, add-ons, and real-time pricing. Solicit sits between item selection (ShopLift or custom) and payment processing (Swipe) to handle complex service configuration. The professional way to solicit services online.

💌
Satisfaction Guaranteed
99.2% of solicitations result in satisfied customers. We're not sure what happens with the other 0.8%, but discretion prevents us from asking.

What You Can Build

The Solicitation Flow

text
ShopLift          Solicit              Swipe
(Products)   ->   (Services)     ->    (Payment)
   |                  |                    |
   v                  v                    v
Cart Items      Plan + Add-ons       Checkout
Selection       Configuration        Processing

Live Demo

Try the Solicit configurator. Gary's coping mechanisms are included.

Gary's Post-Divorce Services

Configure services for the newly single documentation writer

Sara, if you're reading this...

Quickstart

Start soliciting in under 2 minutes.

1. Include the SDK

html
<!-- Load Solicit Core -->
<script src="https://solicit.vagibond.com/solicit-core.js"></script>

<!-- Also load Swipe for payment processing -->
<script src="https://swipe.vagibond.com/swipe-core.js"></script>

2. Initialize with your config

javascript
SolicitCore.init({
  merchantId: 'your-merchant',
  merchantName: 'Your Business',

  plans: [
    { id: 'basic', name: 'Basic', price: 49, description: 'Entry tier' },
    { id: 'pro', name: 'Professional', price: 149, popular: true },
    { id: 'enterprise', name: 'Enterprise', price: 499 }
  ],

  addons: [
    { id: 'priority', name: 'Priority Support', price: 29 }
  ]
});

// Initialize Swipe for payment
SwipeCore.init({ companyName: 'Your Business' });

3. Open the drawer

javascript
// Trigger on button click, CTA, etc.
document.querySelector('.cta-button').addEventListener('click', () => {
  SolicitCore.open();
});

Authentication

Solicit is a client-side SDK - no API keys required. For server-side validation, configure webhooks through your Swipe integration.

Rate Limits

Tier Solicitations/mo Notes
Free Unlimited Client-side only, no limits

SDK Initialization

Configure Solicit with your merchant settings and service options.

javascript
SolicitCore.init({
  // Required
  merchantId: 'your-merchant-id',
  merchantName: 'Your Business Name',

  // Service tiers (radio selection)
  plans: [...],

  // Custom form fields
  fields: [...],

  // Add-on toggles
  addons: [...],

  // External items callback
  getExternalItems: () => [...],

  // Custom pricing logic
  calculatePricing: (state) => {...},

  // Theme customization
  theme: {...},

  // Labels customization
  labels: {...},

  // Callbacks
  onSubmit: (data) => {...},
  onClose: () => {...}
});

Plans Configuration

Define service tiers with radio-style selection.

javascript
plans: [
  {
    id: 'starter',
    name: 'Starter',
    price: 49,
    description: 'Up to 3 solicitations/month'
  },
  {
    id: 'professional',
    name: 'Professional',
    price: 149,
    description: 'Unlimited solicitations',
    popular: true  // Shows "Popular" badge
  },
  {
    id: 'enterprise',
    name: 'Enterprise',
    price: 499,
    description: 'Custom solutions'
  }
]

Custom Fields

Add form fields for service configuration.

javascript
fields: [
  // Select dropdown
  {
    name: 'service_type',
    type: 'select',
    label: 'Service Type',
    options: [
      { value: '', label: 'Select...', disabled: true },
      { value: 'hourly', label: 'Hourly' },
      { value: 'daily', label: 'Daily', price: 50 }  // Shows +$50
    ]
  },

  // Text input
  {
    name: 'company',
    type: 'text',
    label: 'Company Name',
    placeholder: 'Your company'
  },

  // Textarea
  {
    name: 'notes',
    type: 'textarea',
    label: 'Special Requests',
    rows: 4
  },

  // Number input
  {
    name: 'quantity',
    type: 'number',
    label: 'Quantity',
    min: 1,
    max: 100,
    defaultValue: 1
  }
]

Add-ons

Toggle-able add-on services with pricing.

javascript
addons: [
  {
    id: 'priority',
    name: 'Priority Support',
    price: 29,
    description: '24/7 dedicated support line'
  },
  {
    id: 'insurance',
    name: 'Service Insurance',
    price: 99,
    description: 'Full refund if unsatisfied'
  }
]

Custom Pricing

Implement complex pricing logic with the calculatePricing callback.

javascript
calculatePricing: (state) => {
  // state contains:
  // - selectedPlan: { id, name, price, ... }
  // - selectedAddons: Set of addon IDs
  // - externalItems: Array from getExternalItems()
  // - fieldValues: { fieldName: value, ... }
  // - plans: Full plans array
  // - addons: Full addons array

  const planPrice = state.selectedPlan?.price || 0;
  const itemCount = state.externalItems.length || 1;
  const quantity = state.fieldValues.quantity || 1;

  // Calculate add-ons
  let addonsTotal = 0;
  state.selectedAddons.forEach(id => {
    const addon = state.addons.find(a => a.id === id);
    if (addon) addonsTotal += addon.price;
  });

  const total = (planPrice * itemCount * quantity) + addonsTotal;

  return {
    lineItems: [
      { label: 'Items', value: `${itemCount} selected` },
      { label: 'Plan', value: `$${planPrice}` },
      { label: 'Add-ons', value: `$${addonsTotal}` }
    ],
    total: total,
    frequency: '/mo'  // or '', '/hr', 'one-time'
  };
}

Theming

Customize colors to match your brand.

javascript
theme: {
  accent: '#8B0000',           // Primary accent color
  background: '#ffffff',       // Drawer background
  headerBackground: '#f9fafb',
  text: '#111111',
  textMuted: '#666666',
  border: '#e5e7eb',
  inputBackground: '#ffffff',
  inputBorder: '#d1d5db',
  buttonBackground: '#8B0000',  // Falls back to accent
  buttonText: '#ffffff',
  buttonHover: '#6B0000',
  borderRadius: '10px'
}

open()

Opens the Solicit drawer. Resets state and renders fresh content.

javascript
SolicitCore.open();

close()

Closes the drawer. Triggers onClose callback if configured.

javascript
SolicitCore.close();

getState()

Returns current selection state.

javascript
const state = SolicitCore.getState();
// {
//   selectedPlan: { id: 'pro', name: 'Professional', price: 149 },
//   selectedAddons: ['priority', 'insurance'],
//   externalItems: [...],
//   fieldValues: { service_type: 'hourly', notes: '...' }
// }

configure()

Update configuration after initialization.

javascript
SolicitCore.configure({
  plans: newPlans,
  theme: { accent: '#00FF00' }
});

ShopLift Integration

Display cart items from ShopLift in the Solicit drawer.

javascript
SolicitCore.init({
  // Get items from ShopLift cart
  getExternalItems: () => {
    return ShopLiftCore.getCart().map(item => ({
      id: item.id,
      name: item.name,
      subtitle: item.subtitle,
      image: item.image
    }));
  }
});

Swipe Handoff

By default, Solicit hands off to SwipeCore for payment processing.

javascript
// Default behavior (automatic)
// When user clicks submit, Solicit:
// 1. Builds order items from state
// 2. Closes the Solicit drawer
// 3. Calls SwipeCore.showCheckout(items, total)

// Custom submit handling
SolicitCore.init({
  onSubmit: (orderData) => {
    // orderData contains full state
    // Handle custom payment flow
    console.log(orderData.pricing.total);
    myPaymentProcessor.checkout(orderData);
  }
});

Custom Selection

Integrate with any selection UI (hobos, executives, pets, convicts, etc.).

javascript
// Track selected items in your own state
let selectedItems = [];

// Toggle selection
function toggleItem(item) {
  const idx = selectedItems.findIndex(i => i.id === item.id);
  if (idx > -1) {
    selectedItems.splice(idx, 1);
  } else {
    selectedItems.push(item);
  }
}

// Configure Solicit to read from your state
SolicitCore.init({
  getExternalItems: () => selectedItems.map(item => ({
    id: item.id,
    name: item.name,
    subtitle: `$${item.rate}/hr`,
    image: item.photo
  }))
});

Testimoney Integration

Configure paid executive testimonials.

javascript
SolicitCore.init({
  merchantId: 'testi',
  merchantName: 'Testimoney',

  plans: [
    { id: 'starter', name: 'Starter', price: 49, description: 'Up to 3 endorsers' },
    { id: 'growth', name: 'Growth', price: 149, description: 'Up to 10 endorsers', popular: true },
    { id: 'enterprise', name: 'Enterprise', price: 499, description: 'Unlimited' }
  ],

  addons: [
    { id: 'ai-quotes', name: 'AI Quote Suggestions', price: 29 },
    { id: 'insurance', name: 'Testimonial Insurance', price: 99 }
  ],

  getExternalItems: () => selectedExecutives,

  calculatePricing: (state) => {
    // Platform fee + executive rates
    const platformFee = state.selectedPlan?.price || 0;
    const execTotal = state.externalItems.reduce((sum, e) => sum + e.rate, 0);
    // ...
  }
});

Changelog

v1.0.0
February 2026
  • Initial release
  • Plans, fields, add-ons configuration
  • Custom pricing callbacks
  • ShopLift integration
  • Swipe handoff
  • Full theming support