API recipes
Recipe 1: WordPress webhook receiver
Receive AskVault events in WordPress for custom handling:
<?php// In your WP theme or pluginadd_action('rest_api_init', function() { register_rest_route('askvault/v1', '/webhook', [ 'methods' => 'POST', 'callback' => 'askvault_webhook_handler', 'permission_callback' => '__return_true', ]);});
function askvault_webhook_handler($request) { $signature = $request->get_header('X-AskVault-Signature'); $body = $request->get_body(); $secret = get_option('askvault_webhook_secret');
if (!askvault_verify_signature($body, $signature, $secret)) { return new WP_Error('invalid_signature', 'Bad signature', ['status' => 401]); }
$data = json_decode($body, true); // Process based on $data['event'] return ['status' => 'received'];}Add the endpoint as a webhook subscription in AskVault.
Recipe 2: Slack alerts on knowledge gaps
Notify your content team in Slack when the bot can't answer:
from flask import Flask, request, jsonifyimport requests
app = Flask(__name__)SLACK_WEBHOOK = 'https://hooks.slack.com/services/...'
@app.route('/askvault-webhook', methods=['POST'])def webhook(): event = request.json if event['event'] == 'knowledge.gap_detected': message = f":mag: Knowledge gap: '{event['data']['question']}' asked {event['data']['frequency']}x" requests.post(SLACK_WEBHOOK, json={'text': message}) return jsonify({'status': 'ok'})
if __name__ == '__main__': app.run(port=5000)Run as your webhook endpoint.
Recipe 3: Zendesk ticket auto-create
Create Zendesk tickets from AskVault escalations:
const express = require('express');const fetch = require('node-fetch');const app = express();app.use(express.json());
const ZENDESK_SUBDOMAIN = 'yourco';const ZENDESK_USER = 'agent@yourco.co/token';const ZENDESK_TOKEN = 'xxx';
app.post('/askvault-webhook', async (req, res) => { const event = req.body; if (event.event === 'conversation.escalated') { const conv = event.data; await fetch(`https://${ZENDESK_SUBDOMAIN}.zendesk.com/api/v2/tickets.json`, { method: 'POST', headers: { 'Authorization': 'Basic ' + Buffer.from(`${ZENDESK_USER}:${ZENDESK_TOKEN}`).toString('base64'), 'Content-Type': 'application/json', }, body: JSON.stringify({ ticket: { subject: conv.summary, comment: { body: conv.transcript }, requester: { email: conv.customer_email }, priority: conv.priority, } }) }); } res.json({ status: 'ok' });});
app.listen(5000);Recipe 4: HubSpot lead sync
Push captured leads to HubSpot Contacts:
from flask import Flask, request, jsonifyimport requests
app = Flask(__name__)HUBSPOT_KEY = 'xxx'
@app.route('/askvault-webhook', methods=['POST'])def webhook(): event = request.json if event['event'] == 'lead.captured': lead = event['data'] requests.post( 'https://api.hubapi.com/crm/v3/objects/contacts', headers={'Authorization': f'Bearer {HUBSPOT_KEY}'}, json={ 'properties': { 'email': lead['email'], 'firstname': lead['name'].split()[0] if lead.get('name') else '', 'lead_source': 'AskVault Chat', 'askvault_lead_score': lead.get('score', 0), } } ) return jsonify({'status': 'ok'})Common patterns
All recipes share:
- Webhook signature verification (5 lines of code).
- Event type filter (only react to relevant events).
- Idempotency via delivery_id (handle duplicate deliveries).
- Error handling (return 2xx even on internal failure to avoid retry storms).
Limits
- Webhook delivery timeout. 10 seconds.
- Retry attempts. 3 retries over 30 minutes.
- Payload size. Up to 256 KB.
- Concurrent deliveries per endpoint. 10.
Common pitfalls
Recipe runs but ticket not created. Check upstream (Zendesk) credentials.
Slack message not arriving. Check incoming-webhook URL valid.
Duplicate tickets created. Implement idempotency via delivery_id tracking.
FAQ
Can I customize these?
Yes. They're starting points; adapt to your workflow.
Will the AskVault team review my custom recipe?
Yes via support contact. We help with integrations.
Are these recipes open-source?
The patterns are. Your specific implementation is yours.