Skip to main content

Glancito API Reference

Integrate Glancito programmatically with your systems using our REST API.

Getting Started

Base URL

https://api.glancito.com/v1

Authentication

All requests require an API key in the Authorization header:

curl https://api.glancito.com/v1/members \
-H "Authorization: Bearer YOUR_API_KEY"

Getting Your API Key

  1. Go to SettingsAPI & Integrations
  2. Click [Generate API Key]
  3. Copy the key (you won't see it again)
  4. Store it securely (treat like a password)
┌─────────────────────────────────────────┐
│ API Keys │
├─────────────────────────────────────────┤
│ │
│ Active Keys: │
│ ┌─────────────────────────────────┐ │
│ │ key_1a2b3c4d5e6f7g8h │ │
│ │ Created: Mar 1, 2025 │ │
│ │ Last Used: 2 minutes ago │ │
│ │ [Revoke] [Copy] │ │
│ ├─────────────────────────────────┤ │
│ │ key_9i8j7k6l5m4n3o2p │ │
│ │ Created: Jan 15, 2025 │ │
│ │ Last Used: 5 days ago │ │
│ │ [Revoke] [Copy] │ │
│ └─────────────────────────────────┘ │
│ │
│ [+ Generate New Key] │
│ │
└─────────────────────────────────────────┘

Rate Limiting

  • Limit: 1,000 requests per hour
  • Burst: 100 requests per minute
  • Headers returned:
    • X-RateLimit-Limit: 1000
    • X-RateLimit-Remaining: 967
    • X-RateLimit-Reset: 1634567890

If rate limited, you'll receive a 429 Too Many Requests response. Wait and retry.


Response Format

All responses are JSON:

{
"success": true,
"data": {
"id": "member_123",
"email": "sarah@example.com",
"points": 1250
},
"message": "Operation successful"
}

Error Responses

{
"success": false,
"error": {
"code": "MEMBER_NOT_FOUND",
"message": "Member with ID member_999 not found"
}
}

Common error codes:

  • 401_UNAUTHORIZED - Invalid or missing API key
  • 403_FORBIDDEN - API key lacks permission
  • 404_NOT_FOUND - Resource doesn't exist
  • 429_TOO_MANY_REQUESTS - Rate limit exceeded
  • 400_BAD_REQUEST - Invalid request data

Endpoints

Members

List Members

GET /members?limit=50&offset=0

Parameters:

  • limit (optional) - Max 100, default 50
  • offset (optional) - For pagination
  • email (optional) - Filter by email
  • tier (optional) - Filter by tier (gold, silver, bronze)

Response:

{
"success": true,
"data": {
"members": [
{
"id": "member_123",
"email": "sarah@example.com",
"name": "Sarah Johnson",
"phone": "+1 (555) 123-4567",
"points": 1250,
"lifetime_points": 5680,
"tier": "gold",
"joined": "2024-03-15T00:00:00Z",
"last_purchase": "2025-04-10T14:30:00Z"
}
],
"total": 12450,
"limit": 50,
"offset": 0
}
}

Get Member Details

GET /members/{member_id}

Response:

{
"success": true,
"data": {
"id": "member_123",
"email": "sarah@example.com",
"name": "Sarah Johnson",
"phone": "+1 (555) 123-4567",
"address": {
"street": "123 Main St",
"city": "New York",
"state": "NY",
"zip": "10001",
"country": "US"
},
"points": 1250,
"lifetime_points": 5680,
"spent_points": 4430,
"tier": "gold",
"tier_next": "platinum",
"tier_progress": 0.65,
"joined": "2024-03-15T00:00:00Z",
"last_purchase": "2025-04-10T14:30:00Z",
"total_spent": "$8,450",
"purchase_count": 18,
"referrals_made": 4,
"segments": ["high_spenders", "repeat_buyers", "vip"]
}
}

Create Member

POST /members

Request Body:

{
"email": "mike@example.com",
"name": "Mike Chen",
"phone": "+1 (555) 987-6543",
"address": {
"street": "456 Oak Ave",
"city": "San Francisco",
"state": "CA",
"zip": "94102"
}
}

Response:

{
"success": true,
"data": {
"id": "member_456",
"email": "mike@example.com",
"name": "Mike Chen",
"points": 0,
"joined": "2025-04-20T10:00:00Z"
}
}

Update Member

PUT /members/{member_id}

Request Body:

{
"name": "Mike Chen Jr.",
"phone": "+1 (555) 987-6544",
"segments": ["winter_shoppers", "repeat_buyers"]
}

Note: Only provide fields you want to update. Others remain unchanged.


Points

Grant Points

POST /members/{member_id}/points/grant

Request Body:

{
"points": 500,
"reason": "Customer service compensation",
"reference": "INCIDENT_12345",
"internal_note": "Shipping damage on order #12450"
}

Response:

{
"success": true,
"data": {
"member_id": "member_123",
"points_granted": 500,
"previous_balance": 1250,
"new_balance": 1750,
"timestamp": "2025-04-20T10:15:00Z"
}
}

Deduct Points

POST /members/{member_id}/points/deduct

Request Body:

{
"points": 250,
"reason": "Order refund",
"reference": "ORDER_12305"
}

Response:

{
"success": true,
"data": {
"member_id": "member_123",
"points_deducted": 250,
"previous_balance": 1250,
"new_balance": 1000,
"timestamp": "2025-04-20T10:16:00Z"
}
}

Get Transaction History

GET /members/{member_id}/transactions?limit=50&offset=0

Response:

{
"success": true,
"data": {
"transactions": [
{
"id": "txn_789",
"type": "earned",
"points": 250,
"description": "Order #12450",
"reference": "ORDER_12450",
"timestamp": "2025-04-10T14:30:00Z"
},
{
"id": "txn_788",
"type": "redeemed",
"points": -500,
"description": "$10 Off Code Redemption",
"reference": "CODE_ABC123",
"timestamp": "2025-04-05T09:15:00Z"
},
{
"id": "txn_787",
"type": "granted",
"points": 100,
"description": "Admin Bonus",
"reference": "INCIDENT_12345",
"timestamp": "2025-03-22T16:45:00Z"
}
],
"total": 123,
"limit": 50,
"offset": 0
}
}

Rewards

List Rewards

GET /rewards

Response:

{
"success": true,
"data": {
"rewards": [
{
"id": "reward_1",
"name": "$10 Off Your Next Order",
"description": "Valid for 30 days on orders over $50",
"type": "discount_code",
"points_required": 1000,
"discount_value": 10,
"discount_type": "fixed",
"status": "active",
"total_redemptions": 342,
"remaining_budget": null
},
{
"id": "reward_2",
"name": "Free Shipping",
"description": "Free shipping on your next order",
"type": "free_shipping",
"points_required": 500,
"status": "active",
"total_redemptions": 1203
}
]
}
}

Redeem Reward

POST /members/{member_id}/rewards/redeem

Request Body:

{
"reward_id": "reward_1",
"recipient_email": "sarah@example.com"
}

Response:

{
"success": true,
"data": {
"redemption_id": "redeemed_456",
"reward": {
"id": "reward_1",
"name": "$10 Off Your Next Order",
"points_cost": 1000
},
"member": {
"id": "member_123",
"previous_points": 1250,
"new_points": 250
},
"code": "SAVE10ABC",
"expires": "2025-05-20T23:59:59Z",
"timestamp": "2025-04-20T11:00:00Z"
}
}

Campaigns

Create Campaign

POST /campaigns

Request Body:

{
"name": "Spring Sale Campaign",
"subject": "🌸 Spring Savings — 50% Extra Points",
"recipients": {
"segment": "high_spenders"
},
"email": {
"from_name": "The Team",
"from_email": "noreply@store.com",
"body": "Hi {'{'{first_name}'}'}, ...",
"cta_text": "Shop Now",
"cta_url": "https://store.com/spring"
},
"schedule": {
"send_at": "2025-04-25T09:00:00Z"
}
}

Response:

{
"success": true,
"data": {
"id": "campaign_789",
"name": "Spring Sale Campaign",
"status": "scheduled",
"recipients": 2340,
"scheduled_for": "2025-04-25T09:00:00Z"
}
}

Send Campaign Immediately

POST /campaigns/{campaign_id}/send

Response:

{
"success": true,
"data": {
"id": "campaign_789",
"status": "sent",
"recipients": 2340,
"sent_at": "2025-04-20T11:30:00Z"
}
}

Code Examples

Node.js / JavaScript

const fetch = require('node-fetch');

const API_KEY = 'your_api_key_here';
const BASE_URL = 'https://api.glancito.com/v1';

// Grant points to a member
async function grantPoints(memberId, points, reason) {
const response = await fetch(
`${BASE_URL}/members/${memberId}/points/grant`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
points: points,
reason: reason
})
}
);

const data = await response.json();
if (data.success) {
console.log(`Points granted: ${data.data.new_balance}`);
} else {
console.error(`Error: ${data.error.message}`);
}
}

// Usage
grantPoints('member_123', 500, 'Referral bonus');

Python

import requests

API_KEY = 'your_api_key_here'
BASE_URL = 'https://api.glancito.com/v1'

def grant_points(member_id, points, reason):
headers = {
'Authorization': f'Bearer {API_KEY}',
'Content-Type': 'application/json'
}

payload = {
'points': points,
'reason': reason
}

response = requests.post(
f'{BASE_URL}/members/{member_id}/points/grant',
json=payload,
headers=headers
)

data = response.json()
if data['success']:
print(f"Points granted: {data['data']['new_balance']}")
else:
print(f"Error: {data['error']['message']}")

# Usage
grant_points('member_123', 500, 'Referral bonus')

cURL

# Grant points
curl -X POST https://api.glancito.com/v1/members/member_123/points/grant \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"points": 500,
"reason": "Referral bonus"
}'

# List members
curl https://api.glancito.com/v1/members?limit=10 \
-H "Authorization: Bearer YOUR_API_KEY"

# Get member details
curl https://api.glancito.com/v1/members/member_123 \
-H "Authorization: Bearer YOUR_API_KEY"

Common Use Cases

Update Points on External Purchase

When a customer makes a purchase outside your Shopify store:

POST /members/{member_id}/points/grant
{
"points": 50,
"reason": "In-store purchase",
"reference": "INSTORE_5432",
"internal_note": "Customer purchased at pop-up shop on 4/20"
}

Sync CRM Segmentation

Automatically update member segments based on your CRM:

PUT /members/{member_id}
{
"segments": ["high_value", "annual_contract", "vip"]
}

Bulk Bonus Campaign

Award bonus points to a segment for a promotion:

GET /members?tier=gold

# Then for each member:
POST /members/{member_id}/points/grant
{
"points": 500,
"reason": "VIP Appreciation Bonus",
"reference": "CAMPAIGN_VIP_2025Q2"
}

Automated Refund Processing

When you process a refund, reverse the points:

POST /members/{member_id}/points/deduct
{
"points": 250,
"reason": "Order refund",
"reference": "REFUND_12450"
}

Send Personalized Campaign

Trigger campaign to members matching criteria:

POST /campaigns
{
"name": "High-Spender Thank You",
"recipients": {
"segment": "high_spenders"
},
"email": {
"subject": "Thank you {'{'{first_name}'}'}!",
"body": "..."
},
"schedule": {
"send_at": "2025-04-25T09:00:00Z"
}
}

Best Practices

Authentication

✅ Store API keys securely (use environment variables) ✅ Rotate keys periodically (generate new, revoke old) ❌ Never commit API keys to version control ❌ Never expose keys in client-side code

Error Handling

✅ Check success field in responses ✅ Log errors with context for debugging ✅ Implement exponential backoff for retries ✅ Handle rate limits gracefully

Data Validation

✅ Validate email format before creating members ✅ Verify points amounts are reasonable ✅ Check for duplicate members by email ✅ Use transactions for critical operations

Performance

✅ Batch requests when possible ✅ Use pagination for large datasets ✅ Cache member data locally when appropriate ✅ Implement request timeouts


Webhooks

Set up webhooks to receive real-time events:

Events:

  • member.created - New member enrolled
  • member.updated - Member profile changed
  • points.awarded - Points earned
  • points.redeemed - Reward redeemed
  • campaign.sent - Email campaign sent

Configure in SettingsAPI & IntegrationsWebhooks


Support & Questions

For API support:


Next Steps