License Management - Creation Quick Guide

This overview is constructed as a full overview of the inTandem Offering system capabilities. Some of the API's access is restricted by design. Supported token types are clearly mentioned in the API Reference for each end-point

Prerequisites

BASE_URL="https://api.vcita.biz/v3/license"
TOKEN="your_bearer_token_here"
HEADERS='-H "Authorization: Bearer ${TOKEN}" -H "Content-Type: application/json"'

Step 1: Create Individual Offerings

Create Main Package Offering

curl -X POST "${BASE_URL}/offerings" ${HEADERS} -d '{
  "type": "package",
  "SKU": "platinum",
  "display_name": "Platinum Business Package",
  "quantity": 1,
  "payment_type": "monthly",
  "vendor": "in_tandem",
  "is_active": true,
  "trial_period": 14,
  "prices": [{"price": 49.99, "currency": "USD"}],
  "reporting_tags": ["business_management"]
}'

Save the returned offering.uid as PLATINUM_UID.

Create App Offerings

# QuickBooks Integration
curl -X POST "${BASE_URL}/offerings" ${HEADERS} -d '{
  "type": "app",
  "SKU": "quickbooks_integration",
  "display_name": "QuickBooks Integration",
  "quantity": 1,
  "payment_type": "monthly",
  "vendor": "in_tandem",
  "prices": [{"price": 15.00, "currency": "USD"}],
  "reporting_tags": ["integration", "accounting"]
}'

Save as QB_UID.

# CRM App
curl -X POST "${BASE_URL}/offerings" ${HEADERS} -d '{
  "type": "app",
  "SKU": "crm_app",
  "display_name": "Advanced CRM",
  "quantity": 1,
  "payment_type": "monthly",
  "vendor": "in_tandem",
  "prices": [{"price": 20.00, "currency": "USD"}],
  "reporting_tags": ["crm", "sales"]
}'

Save as CRM_UID.

Create Add-on Offerings

# Extra Staff Seats
curl -X POST "${BASE_URL}/offerings" ${HEADERS} -d '{
  "type": "staff_slot",
  "SKU": "staff_seat_5pack",
  "display_name": "5 Additional Staff Seats",
  "quantity": 5,
  "payment_type": "monthly",
  "vendor": "in_tandem",
  "prices": [{"price": 25.00, "currency": "USD"}],
  "reporting_tags": ["staff", "capacity"]
}'

Save as STAFF_UID.

# SMS Credits
curl -X POST "${BASE_URL}/offerings" ${HEADERS} -d '{
  "type": "one_time_purchase",
  "SKU": "sms_1000_pack",
  "display_name": "1000 SMS Credits",
  "quantity": 1000,
  "payment_type": "single_charge",
  "vendor": "in_tandem",
  "prices": [{"price": 10.00, "currency": "USD"}],
  "reporting_tags": ["communication", "sms"]
}'

Save as SMS_UID.

Step 2: Create Bundle Relationships

Bundle Apps with Main Package

# Bundle QuickBooks with Platinum
curl -X POST "${BASE_URL}/bundled_offerings" ${HEADERS} -d '{
  "offering_uid": "'${PLATINUM_UID}'",
  "bundled_offering_uid": "'${QB_UID}'"
}'

# Bundle CRM with Platinum
curl -X POST "${BASE_URL}/bundled_offerings" ${HEADERS} -d '{
  "offering_uid": "'${PLATINUM_UID}'",
  "bundled_offering_uid": "'${CRM_UID}'"
}'

# Bundle SMS Credits with Platinum
curl -X POST "${BASE_URL}/bundled_offerings" ${HEADERS} -d '{
  "offering_uid": "'${PLATINUM_UID}'",
  "bundled_offering_uid": "'${SMS_UID}'"
}'

Verify Bundle Relationships

# List all bundles for Platinum
curl -X GET "${BASE_URL}/bundled_offerings?offering_uid=${PLATINUM_UID}" ${HEADERS}

Step 3: Assign to Partner Directories

Assign Main Package to Directory

curl -X POST "${BASE_URL}/directory_offerings" ${HEADERS} -d '{
  "offering_uid": "'${PLATINUM_UID}'",
  "directory_uid": "partner_directory_123"
}'

Assign Individual Apps (for standalone sales)

# QuickBooks for standalone purchase
curl -X POST "${BASE_URL}/directory_offerings" ${HEADERS} -d '{
  "offering_uid": "'${QB_UID}'",
  "directory_uid": "partner_directory_123"
}'

# CRM for standalone purchase
curl -X POST "${BASE_URL}/directory_offerings" ${HEADERS} -d '{
  "offering_uid": "'${CRM_UID}'",
  "directory_uid": "partner_directory_123"
}'

# Staff seats for upselling
curl -X POST "${BASE_URL}/directory_offerings" ${HEADERS} -d '{
  "offering_uid": "'${STAFF_UID}'",
  "directory_uid": "partner_directory_123"
}'

Assign to Multiple Partner Directories

# Premium partner gets all offerings
for DIRECTORY in "premium_partner_dir" "vip_partner_dir"; do
  curl -X POST "${BASE_URL}/directory_offerings" ${HEADERS} -d '{
    "offering_uid": "'${PLATINUM_UID}'",
    "directory_uid": "'${DIRECTORY}'"
  }'
done

# Standard partner gets limited offerings
curl -X POST "${BASE_URL}/directory_offerings" ${HEADERS} -d '{
  "offering_uid": "'${QB_UID}'",
  "directory_uid": "standard_partner_dir"
}'

Step 4: Verification and Testing

Verify Directory Assignments

# Check what's available in a directory
curl -X GET "${BASE_URL}/directory_offerings?directory_uid=partner_directory_123" ${HEADERS}

Test Offering Retrieval

# Get specific offering details
curl -X GET "${BASE_URL}/offerings/${PLATINUM_UID}" ${HEADERS}

# List offerings filtered by directory
curl -X GET "${BASE_URL}/offerings?directory_id=partner_directory_123&type=package" ${HEADERS}

Complete Automation Script

#!/bin/bash

# Configuration
BASE_URL="https://api.vcita.biz/v3/license"
TOKEN="your_bearer_token_here"
DIRECTORY_UID="partner_directory_123"

# Helper function for API calls
api_call() {
  curl -X "$1" "${BASE_URL}$2" \
    -H "Authorization: Bearer ${TOKEN}" \
    -H "Content-Type: application/json" \
    -d "$3" --silent
}

echo "Creating Platinum package with bundled offerings..."

# Step 1: Create main package
echo "1. Creating Platinum package..."
PLATINUM_RESPONSE=$(api_call POST "/offerings" '{
  "type": "package",
  "SKU": "platinum",
  "display_name": "Platinum Business Package",
  "quantity": 1,
  "payment_type": "monthly",
  "vendor": "in_tandem",
  "prices": [{"price": 49.99, "currency": "USD"}],
  "reporting_tags": ["business_management"]
}')
PLATINUM_UID=$(echo $PLATINUM_RESPONSE | jq -r '.offering.uid')
echo "   Created: $PLATINUM_UID"

# Step 2: Create bundled offerings
echo "2. Creating bundled offerings..."

QB_RESPONSE=$(api_call POST "/offerings" '{
  "type": "app",
  "SKU": "quickbooks_integration",
  "display_name": "QuickBooks Integration",
  "quantity": 1,
  "payment_type": "monthly",
  "vendor": "in_tandem",
  "prices": [{"price": 15.00, "currency": "USD"}]
}')
QB_UID=$(echo $QB_RESPONSE | jq -r '.offering.uid')
echo "   QuickBooks: $QB_UID"

CRM_RESPONSE=$(api_call POST "/offerings" '{
  "type": "app",
  "SKU": "crm_app",
  "display_name": "Advanced CRM",
  "quantity": 1,
  "payment_type": "monthly",
  "vendor": "in_tandem",
  "prices": [{"price": 20.00, "currency": "USD"}]
}')
CRM_UID=$(echo $CRM_RESPONSE | jq -r '.offering.uid')
echo "   CRM: $CRM_UID"

# Step 3: Create bundle relationships
echo "3. Creating bundle relationships..."
api_call POST "/bundled_offerings" "{\"offering_uid\": \"$PLATINUM_UID\", \"bundled_offering_uid\": \"$QB_UID\"}"
api_call POST "/bundled_offerings" "{\"offering_uid\": \"$PLATINUM_UID\", \"bundled_offering_uid\": \"$CRM_UID\"}"
echo "   Bundles created"

# Step 4: Assign to directory
echo "4. Assigning to directory..."
api_call POST "/directory_offerings" "{\"offering_uid\": \"$PLATINUM_UID\", \"directory_uid\": \"$DIRECTORY_UID\"}"
api_call POST "/directory_offerings" "{\"offering_uid\": \"$QB_UID\", \"directory_uid\": \"$DIRECTORY_UID\"}"
api_call POST "/directory_offerings" "{\"offering_uid\": \"$CRM_UID\", \"directory_uid\": \"$DIRECTORY_UID\"}"
echo "   Directory assignments complete"

echo "Setup complete! Platinum package available in directory: $DIRECTORY_UID"
echo "Main offering UID: $PLATINUM_UID"

Common Creation Patterns

Pattern: Tiered Service Packages

# Basic Package
BASIC_RESPONSE=$(api_call POST "/offerings" '{
  "type": "package",
  "SKU": "basic",
  "display_name": "Basic Package",
  "quantity": 1,
  "payment_type": "monthly",
  "prices": [{"price": 19.99, "currency": "USD"}]
}')

# Premium Package (includes Basic features + extras)
PREMIUM_RESPONSE=$(api_call POST "/offerings" '{
  "type": "package", 
  "SKU": "premium",
  "display_name": "Premium Package",
  "quantity": 1,
  "payment_type": "monthly",
  "prices": [{"price": 39.99, "currency": "USD"}]
}')

# Bundle premium apps with Premium package only
api_call POST "/bundled_offerings" "{\"offering_uid\": \"$PREMIUM_UID\", \"bundled_offering_uid\": \"$ADVANCED_ANALYTICS_UID\"}"

Pattern: Partner-Specific Offerings

# Create partner-specific version
PARTNER_SPECIAL=$(api_call POST "/offerings" '{
  "type": "package",
  "SKU": "platinum_partner_special",
  "display_name": "Platinum - Partner Special Rate",
  "quantity": 1,
  "payment_type": "monthly",
  "prices": [{"price": 35.00, "currency": "USD"}],
  "reporting_tags": ["partner_special"]
}')

# Assign only to specific partner
api_call POST "/directory_offerings" "{\"offering_uid\": \"$PARTNER_SPECIAL_UID\", \"directory_uid\": \"vip_partner_only\"}"

Key Rules to Remember

  1. Bundle Dependencies: All bundled offerings must be assigned to the same directories as the parent offering
  2. Bundle Relationships: Create offerings first, then bundle relationships, then directory assignments
  3. Directory Isolation: Offerings not assigned to a directory cannot be sold by that partner
  4. Deletion Restrictions: Cannot delete offerings that have been used to create subscriptions
  5. Self-Bundling: Cannot bundle an offering to itself

Quick Verification Commands

# Check bundle relationships
curl -X GET "${BASE_URL}/bundled_offerings?offering_uid=${PLATINUM_UID}" ${HEADERS}

# Check directory assignments  
curl -X GET "${BASE_URL}/directory_offerings?directory_uid=${DIRECTORY_UID}" ${HEADERS}

# Verify offering details
curl -X GET "${BASE_URL}/offerings/${PLATINUM_UID}" ${HEADERS}