Selgora API: Getting Started Guide
Access and integrate with Selgora programmatically using our RESTful API
Selgora API: Getting Started Guide
Unlock the full power of Selgora by integrating with our RESTful API. Build custom integrations, automate workflows, and extend functionality beyond the dashboard.
API Overview
What You Can Do
Read Operations:
- Fetch contacts and their data
- Retrieve course information
- Get order history
- Access analytics data
- List products and offers
Write Operations:
- Create/update contacts
- Trigger email campaigns
- Grant/revoke access
- Create orders
- Update custom fields
Real-time Events:
- Purchase notifications
- Contact updates
- Course completions
- Subscription changes
Getting Started
Step 1: Generate API Keys
Dashboard > Settings > API
Click: Generate New Key
Name: "My Integration"
Permissions: Select scopes
Key Format:
Public Key: pk_live_51He3gDA3k9fEM...
Secret Key: sk_live_51He3gDA3k9fEM...
⚠️ Important:
- Store keys securely
- Never expose secret keys in client-side code
- Rotate keys regularly
- Use environment variables
Step 2: Authentication
All API requests require authentication:
curl https://api.selgora.com/v1/contacts \
-H "Authorization: Bearer sk_live_your_secret_key"
Headers Required:
Authorization: Bearer YOUR_SECRET_KEY
Content-Type: application/json
Accept: application/json
Step 3: Make Your First Request
Test Connection:
curl https://api.selgora.com/v1/account \
-H "Authorization: Bearer sk_live_your_secret_key"
Response:
{
"account": {
"id": "acc_123",
"name": "Your Account",
"email": "you@example.com",
"plan": "scale",
"created_at": "2024-01-15T10:00:00Z"
}
}
API Endpoints
Base URL
https://api.selgora.com/v1
Core Resources
Contacts
List Contacts:
GET /contacts
Parameters:
page
(integer): Page numberlimit
(integer): Items per page (max 100)tag
(string): Filter by tagcreated_after
(datetime): Filter by date
Example Request:
curl https://api.selgora.com/v1/contacts?page=1&limit=50 \
-H "Authorization: Bearer sk_live_key"
Response:
{
"contacts": [
{
"id": "con_123",
"email": "john@example.com",
"first_name": "John",
"last_name": "Doe",
"tags": ["customer", "vip"],
"created_at": "2024-01-15T10:00:00Z",
"custom_fields": {
"company": "Acme Inc",
"role": "CEO"
}
}
],
"pagination": {
"page": 1,
"limit": 50,
"total": 234,
"pages": 5
}
}
Create Contact:
POST /contacts
Body:
{
"email": "new@example.com",
"first_name": "Jane",
"last_name": "Smith",
"tags": ["lead"],
"custom_fields": {
"source": "api",
"interest": "courses"
}
}
Update Contact:
PUT /contacts/{id}
Delete Contact:
DELETE /contacts/{id}
Products & Offers
List Products:
GET /products
Response:
{
"products": [
{
"id": "prod_123",
"name": "Complete Course",
"type": "course",
"price": 19700,
"currency": "USD",
"status": "active",
"created_at": "2024-01-01T00:00:00Z"
}
]
}
Get Product Details:
GET /products/{id}
Orders
List Orders:
GET /orders
Parameters:
status
: pending|completed|refundedcustomer_email
: Filter by customerproduct_id
: Filter by productcreated_after
: Date filter
Create Order (Manual):
POST /orders
Body:
{
"customer_email": "customer@example.com",
"products": [
{
"id": "prod_123",
"quantity": 1
}
],
"payment_method": "manual",
"send_receipt": true
}
Access Management
Grant Access:
POST /access/grant
Body:
{
"contact_id": "con_123",
"product_id": "prod_456",
"expires_at": "2025-01-01T00:00:00Z"
}
Revoke Access:
POST /access/revoke
Body:
{
"contact_id": "con_123",
"product_id": "prod_456"
}
Working with Webhooks
Setting Up Webhooks
POST /webhooks
Body:
{
"url": "https://yourapp.com/webhook",
"events": [
"order.completed",
"contact.created",
"subscription.cancelled"
],
"secret": "whsec_your_secret"
}
Webhook Events
Available Events:
order.completed
order.refunded
contact.created
contact.updated
contact.deleted
subscription.created
subscription.updated
subscription.cancelled
course.completed
email.opened
email.clicked
Webhook Payload
{
"event": "order.completed",
"created_at": "2024-11-15T10:00:00Z",
"data": {
"order": {
"id": "ord_123",
"amount": 19700,
"customer": {
"email": "customer@example.com"
},
"products": [...]
}
}
}
Verifying Webhooks
import hmac
import hashlib
def verify_webhook(payload, signature, secret):
expected = hmac.new(
secret.encode(),
payload.encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)
Rate Limiting
Limits
- Default: 1000 requests per hour
- Burst: 100 requests per minute
- Scale Plan: 5000 requests per hour
- Enterprise: Unlimited
Headers
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1699180800
Handling Rate Limits
async function apiRequest(url, options) {
const response = await fetch(url, options);
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After');
await sleep(retryAfter * 1000);
return apiRequest(url, options);
}
return response;
}
Error Handling
Error Response Format
{
"error": {
"type": "invalid_request",
"message": "The email field is required",
"field": "email",
"code": "missing_required_field"
}
}
Common Error Codes
Code | Description | Solution |
---|---|---|
400 | Bad Request | Check request format |
401 | Unauthorized | Verify API key |
403 | Forbidden | Check permissions |
404 | Not Found | Verify resource exists |
429 | Rate Limited | Wait and retry |
500 | Server Error | Contact support |
SDK & Libraries
Official SDKs
Node.js:
npm install @selgora/node
const Selgora = require('@selgora/node');
const selgora = new Selgora('sk_live_key');
// Create contact
const contact = await selgora.contacts.create({
email: 'new@example.com',
first_name: 'John'
});
Python:
pip install selgora
import selgora
client = selgora.Client('sk_live_key')
# List contacts
contacts = client.contacts.list(limit=50)
PHP:
composer require selgora/selgora-php
$selgora = new \Selgora\Client('sk_live_key');
// Get contact
$contact = $selgora->contacts->retrieve('con_123');
Example Integrations
Sync with CRM
// Sync Selgora contacts to your CRM
async function syncContacts() {
const contacts = await selgora.contacts.list({
limit: 100,
created_after: lastSyncDate
});
for (const contact of contacts) {
await crm.createOrUpdate({
email: contact.email,
customFields: {
selgora_id: contact.id,
selgora_tags: contact.tags.join(',')
}
});
}
}
Automate Access
# Grant access after external payment
def handle_payment_success(payment):
client.access.grant(
contact_id=payment.customer_id,
product_id='prod_123',
expires_at=datetime.now() + timedelta(days=365)
)
client.contacts.update(
payment.customer_id,
tags=['customer', 'premium']
)
Analytics Dashboard
// Fetch data for custom dashboard
async function getDashboardData() {
const [orders, contacts, products] = await Promise.all([
selgora.orders.list({ created_after: startOfMonth }),
selgora.contacts.stats(),
selgora.products.list({ status: 'active' })
]);
return {
revenue: orders.reduce((sum, o) => sum + o.amount, 0),
newContacts: contacts.new_this_month,
activeProducts: products.length
};
}
Best Practices
Security
- Never expose secret keys
- Use HTTPS always
- Validate webhooks
- Implement retry logic
- Log API interactions
Performance
- Cache responses when possible
- Use pagination for large datasets
- Batch operations
- Implement exponential backoff
- Use webhooks vs. polling
Error Handling
class ApiClient {
async request(method, path, data) {
try {
const response = await fetch(path, {
method,
headers: this.headers,
body: JSON.stringify(data)
});
if (!response.ok) {
throw new ApiError(response);
}
return response.json();
} catch (error) {
this.logError(error);
throw error;
}
}
}
Quick Start Examples
Create Your First Integration
// 1. Initialize client
const selgora = new Selgora(process.env.SELGORA_API_KEY);
// 2. Create a contact
const contact = await selgora.contacts.create({
email: 'test@example.com',
tags: ['api-test']
});
// 3. Grant access to a product
await selgora.access.grant({
contact_id: contact.id,
product_id: 'prod_123'
});
// 4. Send a welcome email
await selgora.emails.send({
to: contact.email,
template: 'welcome',
data: { name: contact.first_name }
});
console.log('Integration successful!');
Remember: The API is powerful—use it responsibly. Start with read operations, test thoroughly, and gradually add complexity. When in doubt, check the API reference or contact support!
Was this article helpful?
Your feedback helps us improve our content