SDKs & client libraries
Hook0 has official SDKs for several programming languages. They share the same design patterns but stay idiomatic to each language.
Set up environment variables
# Set your service token (from dashboard)
export HOOK0_TOKEN="YOUR_TOKEN_HERE"
export HOOK0_API="https://app.hook0.com/api/v1" # Replace by your domain (or http://localhost:8081 locally)
# Set your application ID (shown in dashboard URL or application details)
export APP_ID="YOUR_APPLICATION_ID_HERE"
Save these values:
# Save to .env file for later use
cat > .env <<EOF
HOOK0_TOKEN=$HOOK0_TOKEN
HOOK0_API=$HOOK0_API
APP_ID=$APP_ID
EOF
Official SDKs
JavaScript/TypeScript SDK
TypeScript SDK for Node.js with event sending.
Features:
- Event sending with type definitions
- Event type management (upsert)
- Webhook signature verification
- Node.js compatibility
Installation:
npm install hook0-client
Quick start:
import { Hook0Client, Event } from 'hook0-client';
const hook0 = new Hook0Client(
'http://localhost:8081',
'app_1234567890',
'{YOUR_TOKEN}'
);
const event = new Event(
'user.account.created',
JSON.stringify({ user_id: 123 }),
'application/json',
{ source: 'api' }
);
await hook0.sendEvent(event);
Rust SDK
Native Rust SDK for sending events and verifying webhook signatures.
Features:
- Event sending with typed payloads
- Event type management (upsert)
- Webhook signature verification (v0 and v1)
- Optional feature flags (
producer,consumer)
Installation:
[dependencies]
hook0-client = "1"
Quick start:
use hook0_client::{Hook0Client, Event};
use reqwest::Url;
use uuid::Uuid;
use std::borrow::Cow;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let api_url = Url::parse("http://localhost:8081/api/v1")?;
let application_id = Uuid::parse_str("your-app-id-here")?;
let client = Hook0Client::new(api_url, application_id, "{YOUR_TOKEN}")?;
let event = Event {
event_id: &None,
event_type: "user.account.created",
payload: Cow::Borrowed(r#"{"user_id": "123"}"#),
payload_content_type: "application/json",
metadata: None,
occurred_at: None,
labels: vec![("environment".to_string(), "production".to_string())],
};
let event_id = client.send_event(&event).await?;
println!("Event sent: {}", event_id);
Ok(())
}
Additional language support
Official SDKs for Python, Go, PHP, Ruby, Java, and .NET are planned. In the meantime, use the REST API directly with your language's HTTP client.
Using the REST API
Everything Hook0 does is available through the REST API. Here is how to send events in a few languages:
Python Example:
import requests
response = requests.post(
'http://localhost:8081',
headers={
'Authorization': 'Bearer {YOUR_TOKEN}',
'Content-Type': 'application/json'
},
json={
'event_type': 'user.account.created',
'payload': {'user_id': 123}
}
)
Go Example:
import "net/http"
import "encoding/json"
event := map[string]interface{}{
"event_type": "user.account.created",
"payload": map[string]interface{}{"user_id": 123},
}
data, _ := json.Marshal(event)
req, _ := http.NewRequest("POST", "https://app.hook0.com/api/v1/event", bytes.NewBuffer(data))
req.Header.Set("Authorization", "Bearer {YOUR_TOKEN}")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
Core SDK features
All official Hook0 SDKs provide:
Authentication and security
- Authentication via Biscuit tokens (user sessions) and Service tokens (programmatic access)
- Webhook signature verification
- TLS/SSL support
- Secure credential management
API operations
- Event sending (single events)
- Application management (via REST API)
- Subscription CRUD operations (via REST API)
- Event type management
- Delivery status tracking (via REST API)
Developer experience
- Type safety and auto-completion
- Error handling with typed errors
- Structured logging
- Documentation with examples
Common usage patterns
Sending events
// JavaScript/TypeScript
const event = new Event(
'order.checkout.completed',
JSON.stringify({
order_id: 'ord_123',
total: 99.99
}),
'application/json',
{
environment: 'production',
region: 'us-west'
}
);
await hook0.sendEvent(event);
# Using cURL
curl -X POST $HOOK0_API/event \
-H "Authorization: Bearer $HOOK0_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"event_type": "order.checkout.completed",
"payload": {
"order_id": "ord_123",
"total": 99.99
},
"labels": {
"environment": "production",
"region": "us-west"
}
}'
Managing subscriptions
# Using the REST API
curl -X POST $HOOK0_API/subscriptions \
-H "Authorization: Bearer $HOOK0_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"description": "Order Events",
"event_types": ["order.checkout.completed", "order.shipped"],
"target": {
"type": "http",
"url": "https://api.example.com/webhooks",
"method": "POST"
}
}'
Webhook verification
// JavaScript/TypeScript
import { verifyWebhookSignature } from 'hook0-client';
// Note: Express.js normalizes all header names to lowercase
// Capture raw body for signature verification
app.post('/webhook', express.json({
verify: (req, res, buf) => { req.rawBody = buf; }
}), (req, res) => {
const signature = req.headers['x-hook0-signature'];
// Use raw body for signature verification, not JSON.stringify(req.body)
const rawBodyString = req.rawBody.toString('utf8');
const headers = new Headers();
Object.entries(req.headers).forEach(([key, value]) => {
if (typeof value === 'string') headers.set(key, value);
});
try {
const isValid = verifyWebhookSignature(
signature,
rawBodyString,
headers,
secret,
300 // 5-minute tolerance
);
if (!isValid) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Process webhook (already parsed via req.body)...
} catch (error) {
return res.status(401).json({ error: 'Invalid signature' });
}
});
Error handling
SDKs return typed errors you can match on:
// JavaScript/TypeScript
import { Hook0ClientError } from 'hook0-client';
try {
const eventId = await hook0.sendEvent(event);
} catch (error) {
if (error instanceof Hook0ClientError) {
console.error('Hook0 error:', error.message);
if (error.message.includes('Invalid event type')) {
// Handle invalid event type format
} else if (error.message.includes('failed')) {
// Retry logic
}
}
}
// REST API error handling
fetch('http://localhost:8081', {
method: 'POST',
headers: {
'Authorization': 'Bearer {YOUR_TOKEN}',
'Content-Type': 'application/json'
},
body: JSON.stringify(event)
})
.then(response => {
if (response.status === 429) {
// Rate limited - check X-RateLimit-Reset header
const resetTime = response.headers.get('X-RateLimit-Reset');
// Implement retry logic
} else if (!response.ok) {
// Handle other errors
}
});
Configuration
TypeScript SDK configuration
const hook0 = new Hook0Client(
'http://localhost:8081', // API URL
'app_1234567890', // Application ID
'{YOUR_TOKEN}', // Authentication token
false // Debug mode (optional)
);
REST API configuration
When using the REST API directly, configure your HTTP client:
// Example with axios
const apiClient = axios.create({
baseURL: 'http://localhost:8081',
headers: {
'Authorization': 'Bearer {YOUR_TOKEN}',
'Content-Type': 'application/json'
},
timeout: 30000
});
Testing
Testing with TypeScript SDK
// Mock fetch for testing
import { Hook0Client, Event } from 'hook0-client';
import { jest } from '@jest/globals';
test('should send event', async () => {
global.fetch = jest.fn().mockResolvedValueOnce({
ok: true,
text: async () => ''
});
const client = new Hook0Client(
'http://localhost:8081',
'app_test',
'test_token'
);
const event = new Event(
'test.event',
JSON.stringify({ test: true }),
'application/json',
{}
);
await client.sendEvent(event);
expect(fetch).toHaveBeenCalledWith(
'http://localhost:8081',
expect.objectContaining({
method: 'POST'
})
);
});
SDK development guidelines
Want to contribute an SDK? Here is what we expect:
Requirements checklist
- All essential endpoints implemented
- Biscuit token and Service token support
- Typed error messages
- >80% test coverage
- API docs with examples
- Working example applications
- Automated testing and publishing
Best practices
- Write idiomatic code for your language
- Provide type definitions where possible
- Implement async/await or promises
- Handle connection pooling and cleanup
- Follow semantic versioning
- Maintain a changelog
Getting help
Documentation
- API Reference - REST API documentation
- Tutorials - Step-by-step guides
- How-to Guides - Problem-solving guides
Support channels
- GitHub Issues - SDK-specific issue tracking
- Discord - Community support
- Stack Overflow - #hook0 tag
- [email protected] - For critical issues
Contributing
To contribute to our SDK:
- Open an issue to discuss your proposal
- Follow the requirements checklist above
- Submit for review
- Enjoy :)