Documentation Index Fetch the complete documentation index at: https://offergrid.io/docs/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The Offergrid Provider API lets you automate offer management and order fulfillment by integrating directly with your existing systems.
Getting Started
1. Get Your API Key
Generate a Team API Key from your dashboard:
Sign in to offergrid.io
Navigate to Settings → API Keys
Click Generate New Key
Save the key securely
See Authentication for detailed instructions.
2. Choose Your Integration Approach
Option A: Direct API Calls
Use HTTP requests from your application
Full control and flexibility
Best for custom integrations
Option B: Webhooks
Receive real-time notifications
Event-driven architecture
Best for order automation
Option C: Scheduled Sync
Poll API periodically
Simple to implement
Best for batch processing
Common Integration Patterns
Pattern 1: Automated Offer Sync
Sync your internal product catalog to Offergrid:
// Example: Daily sync of offers from your CRM
async function syncOffers () {
const internalOffers = await fetchFromCRM ();
for ( const offer of internalOffers ) {
const offergridOffer = transformToOffergridFormat ( offer );
// Check if offer exists
const existing = await findOfferBySKU ( offer . sku );
if ( existing ) {
// Update existing offer
await updateOffer ( existing . id , offergridOffer );
} else {
// Create new offer
await createOffer ( offergridOffer );
}
}
}
// Transform your internal format to Offergrid format
function transformToOffergridFormat ( internalOffer ) {
return {
name: internalOffer . productName ,
category: mapCategory ( internalOffer . type ),
sku: internalOffer . sku ,
monthlyPrice: internalOffer . price ,
status: internalOffer . isActive ? 'active' : 'inactive' ,
description: internalOffer . description ,
serviceSpecificData: {
// Map category-specific fields
},
};
}
Run this sync:
Daily : For frequently changing catalogs
Hourly : For dynamic pricing
On-demand : When products update in your system
Pattern 2: Real-Time Order Processing
Use webhooks to process orders immediately:
// Example: Webhook endpoint to receive new orders
app . post ( '/webhooks/offergrid/orders' , async ( req , res ) => {
const { event , orderId , itemId } = req . body ;
if ( event === 'order.created' ) {
// Fetch full order details
const order = await fetchOrderFromOffergrid ( itemId );
// Check service availability
const available = await checkServiceability ( order . serviceAddress );
if ( available ) {
// Auto-accept and create work order in your system
await acceptOrder ( itemId );
await createWorkOrder ( order );
// Schedule customer contact
await scheduleCustomerCall ( order );
} else {
// Reject with reason
await rejectOrder ( itemId , 'Service not available at this address' );
}
}
res . status ( 200 ). send ( 'OK' );
});
Pattern 3: Status Sync from Fulfillment System
Update Offergrid when your internal status changes:
// Example: Update Offergrid when your CRM updates order status
async function onWorkOrderStatusChange ( workOrder ) {
const statusMap = {
scheduled: 'scheduled' ,
in_progress: 'in_progress' ,
completed: 'completed' ,
failed: 'failed' ,
};
await updateOffergridOrderStatus ( workOrder . offergridItemId , {
status: statusMap [ workOrder . status ],
providerNotes: workOrder . notes ,
scheduledFor: workOrder . appointmentDate ,
metadata: {
workOrderId: workOrder . id ,
technicianId: workOrder . technicianId ,
},
});
}
// Hook into your CRM's status change events
crmSystem . on ( 'workorder.status_changed' , onWorkOrderStatusChange );
Core API Operations
Managing Offers
{
"name" : "High-Speed Internet 1000 Mbps" ,
"category" : "internet" ,
"status" : "active" ,
"monthlyPrice" : 59.99
}
Returns the created offer with assigned ID.
Returns array of all offers for your team.
PATCH /provider/offers/{id}
{
"monthlyPrice" : 49.99 ,
"status" : "active"
}
Updates only the fields provided.
DELETE /provider/offers/{id}
Permanently removes the offer.
Managing Orders
GET /provider/orders?status=pending
Filter by status to get orders needing attention.
GET /provider/orders/{itemId}
Returns full order details including customer info and service address.
PATCH /provider/orders/{itemId}/status
{
"status" : "accepted" ,
"providerNotes" : "Order accepted. Customer will be contacted within 24 hours." ,
"metadata" : {}
}
Updates order status and adds notes for reseller.
Error Handling
Implement robust error handling:
async function safeApiCall ( apiFunction , retries = 3 ) {
for ( let i = 0 ; i < retries ; i ++ ) {
try {
return await apiFunction ();
} catch ( error ) {
if ( error . status === 401 ) {
// Authentication error - don't retry
throw new Error ( 'Invalid API key' );
}
if ( error . status === 429 ) {
// Rate limited - wait and retry
await sleep ( 2 ** i * 1000 );
continue ;
}
if ( error . status >= 500 ) {
// Server error - retry
await sleep ( 2 ** i * 1000 );
continue ;
}
// Client error (4xx) - don't retry
throw error ;
}
}
throw new Error ( 'Max retries exceeded' );
}
Rate Limiting
Be mindful of rate limits:
Burst : 100 requests per minute
Sustained : 10,000 requests per hour
Best practices :
Implement exponential backoff
Cache responses when appropriate
Batch operations where possible
Use webhooks instead of polling
Security Best Practices
Use environment variables or secure key management: // ✅ Good
const apiKey = process . env . OFFERGRID_API_KEY ;
// ❌ Bad
const apiKey = 'pk_live_abc123...' ; // Never hardcode!
Always use https:// endpoints, never http://.
Validate webhook signatures
Verify webhook requests actually come from Offergrid: function verifyWebhook ( req ) {
const signature = req . headers [ 'x-offergrid-signature' ];
const payload = JSON . stringify ( req . body );
const expected = createHmac ( 'sha256' , webhookSecret )
. update ( payload )
. digest ( 'hex' );
return signature === expected ;
}
Implement request timeouts
Don’t let API calls hang indefinitely: const response = await fetch ( url , {
headers: { 'x-api-key' : apiKey },
signal: AbortSignal . timeout ( 10000 ), // 10 second timeout
});
Testing Your Integration
1. Use Draft Offers
Test with status: "draft" offers that won’t be visible to resellers:
{
"name" : "Test Offer - Do Not Order" ,
"status" : "draft" ,
"monthlyPrice" : 0.01
}
2. Create Test Orders
Work with support to create test orders for validation.
3. Monitor Logs
Watch your integration logs for errors:
const logger = createLogger ({
level: 'info' ,
format: format . json (),
});
logger . info ( 'Order accepted' , {
orderId: order . id ,
offerId: order . offerId ,
status: 'accepted' ,
});
Example Integration
Full example of a provider integration:
import { OffergridClient } from '@offergrid/node-sdk' ;
const client = new OffergridClient ({
apiKey: process . env . OFFERGRID_API_KEY ,
});
// Sync offers daily
cron . schedule ( '0 2 * * *' , async () => {
await syncOffersToOffergrid ();
});
// Process new orders via webhook
app . post ( '/webhooks/offergrid' , async ( req , res ) => {
const { event , itemId } = req . body ;
if ( event === 'order.created' ) {
await processNewOrder ( itemId );
}
res . sendStatus ( 200 );
});
// Update Offergrid when internal status changes
async function onInternalStatusChange ( workOrder ) {
await client . orders . updateStatus ( workOrder . offergridItemId , {
status: workOrder . status ,
providerNotes: workOrder . notes ,
});
}
Next Steps
API Reference Complete API documentation
Webhooks Set up real-time notifications
Authentication API key management
Order Fulfillment Learn about order processing