Quick Start Guide
Get your ordering channel integrated with OneTablet in a few steps.
Prerequisites
Before you begin, ensure you have:
- API credentials from OneTablet
- An API server capable of receiving HTTPS requests from OneTablet
- Store IDs for the restaurants in your network
Integration Summary
| Direction | What Happens |
|---|---|
| OneTablet → You | We push menus, confirm/reject orders, send availability updates |
| You → OneTablet | You send new orders, cancellation requests, delivery status updates |
Step 1: Implement Webhook Endpoints
OneTablet will call these callback endpoints on your server. See Webhooks for complete details.
Order Confirmation Endpoint
Receive order accept/reject decisions from restaurants:
// PATCH /orders/{order_id}
app.patch('/orders/:orderId', async (req, res) => {
const { order_status, merchant_supplied_id, prep_time, failure_reason } = req.body;
if (order_status === 'success') {
// Order accepted - update your system
await updateOrderStatus(req.params.orderId, 'confirmed', prep_time);
} else {
// Order rejected - notify customer
await handleOrderRejection(req.params.orderId, failure_reason);
}
res.status(200).send('OK');
});
Menu Push Endpoint
Receive menu updates from OneTablet:
// PATCH /menus/{menu_id}
app.patch('/menus/:menuId', async (req, res) => {
const { store, menu, open_hours, special_hours } = req.body;
// Store the menu in your system
await saveMenu(store.merchant_supplied_id, menu);
res.status(200).json({ menu_id: 'your-menu-uuid' });
});
Item Availability Endpoint
Receive 86ing updates when items become unavailable:
// PUT /stores/{store_id}/items/status
app.put('/stores/:storeId/items/status', async (req, res) => {
const items = req.body; // Array of { merchant_supplied_id, is_active }
for (const item of items) {
await updateItemAvailability(req.params.storeId, item.merchant_supplied_id, item.is_active);
}
res.status(200).send('OK');
});
Step 2: Call OneTablet's API to Submit Orders
When a customer places an order on your platform, call OneTablet's API. See API Endpoints for complete details.
async function submitOrderToOneTablet(order) {
const payload = {
event: {
type: 'OrderCreate',
status: 'NEW'
},
order: {
id: order.id,
store_order_cart_id: order.cartId,
delivery_short_code: generateShortCode(),
store: {
merchant_supplied_id: order.storeId,
provider_type: 'your_platform',
timezone: 'America/New_York',
store_business: {
auto_release_enabled: true
}
},
consumer: {
id: order.customerId,
email: order.customerEmail,
first_name: order.customerFirstName,
last_name: order.customerLastName,
phone: order.customerPhone
},
categories: order.categories,
order_special_instructions: order.notes,
subtotal: order.subtotal,
tax: order.tax,
merchant_tip_amount: order.tip,
is_pickup: order.isPickup,
estimated_pickup_time: order.estimatedReadyTime,
fulfillment_type: order.isPickup ? 'pickup' : 'dx_delivery',
delivery_address: order.deliveryAddress,
experience: 'YOUR_PLATFORM',
commission_type: 'regular',
is_tax_remitted_by_doordash: false,
tax_amount_remitted_by_doordash: 0,
tax_transaction_id: order.taxTransactionId,
applied_discounts: order.discounts || []
}
};
const response = await fetch(ONETABLET_API_URL + '/orders', {
method: 'POST',
headers: {
'Authorization': `Bearer ${await generateToken()}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
});
if (!response.ok) {
throw new Error(`Order submission failed: ${response.status}`);
}
}
Step 3: Handle the Order Lifecycle
1. You Submit Order
Your Platform ──[POST /orders]──► OneTablet ──► Restaurant POS
2. Restaurant Accepts/Rejects (Webhook to You)
Restaurant POS ──► OneTablet ──[PATCH /orders/{id}]──► Your Webhook Endpoint
Handle the confirmation webhook:
app.patch('/orders/:orderId', async (req, res) => {
const { order_status, prep_time, failure_reason } = req.body;
if (order_status === 'success') {
await notifyCustomer(req.params.orderId, 'Order confirmed!', prep_time);
} else {
await notifyCustomer(req.params.orderId, `Order rejected: ${failure_reason}`);
await processRefund(req.params.orderId);
}
res.status(200).send('OK');
});
3. Order Ready (Webhook to You)
Restaurant POS ──► OneTablet ──[PATCH /orders/{id}/events/order_ready_for_pickup]──► Your Webhook Endpoint
4. Delivery Updates (if applicable)
You call OneTablet's API to send delivery status updates:
async function sendDeliveryUpdate(orderId, status, dasherInfo) {
await fetch(ONETABLET_API_URL + `/orders/${orderId}/delivery-status`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${await generateToken()}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
status: status, // arriving_at_store, arrived_at_store, etc.
dasher: dasherInfo
})
});
}
Step 4: Pull Menus (Optional)
While OneTablet pushes menus to you, you can also pull them on-demand:
# Get all menus for a store
curl -X GET "https://integration.onetablet.example/pull/menus/store-123" \
-H "Authorization: Bearer {token}"
See Menu Pull API for details.
Next Steps
- Authentication - Learn about authentication methods
- API Endpoints - OneTablet API endpoints you call
- Webhooks - Callback endpoints you expose
- Order Schema - Complete order data structure
- Menu Schema - Full menu schema documentation
Common Issues
Order not reaching restaurant
- Verify your webhook payload matches the expected schema
- Check authentication credentials
- Ensure store ID is correct and store is active
Not receiving menu updates
- Verify your menu push endpoint is accessible
- Return HTTP 200 to acknowledge receipt
- Check firewall rules for OneTablet IPs
Item availability out of sync
- Implement your item availability endpoint
- Return HTTP 200 promptly to acknowledge updates