All API endpoints require two forms of authentication:
1. Bearer Token
Include your API key in the Authorization header:
Authorization: Bearer YOUR_API_KEY
2. Request Signing
Include an HMAC signature in the X-Signature header:
X-Signature: <HMAC-SHA256 hex-encoded signature>
The signature payload differs by HTTP method:
- POST/PUT/PATCH/DELETE requests: Sign the request body
- GET requests: Sign the full request URI (path + query string)
The signature is calculated using HMAC-SHA256 with your API secret.
How to calculate
- Determine the payload:
- POST/PUT/PATCH/DELETE: Use the raw request body
- GET: Use the full request URI (e.g.,
/v2/members?limit=10&offset=0)
- Calculate HMAC-SHA256 of the payload using your API secret
- Hex-encode the result (64 character lowercase string)
Example: POST request (Python)
For POST/PUT/PATCH/DELETE requests, sign the request body:
import json
import hmac
import hashlib
import requests
def create_topic(name: str, members: list[str], description: str = None, external_id: str = None) -> dict:
"""Create a topic in Zenzap with HMAC signature."""
# Build request body
body = {
"name": name,
"members": members,
}
if description:
body["description"] = description
if external_id:
body["externalId"] = external_id
# Serialize body (no spaces for consistent signing)
body_json = json.dumps(body, separators=(",", ":"))
# Create HMAC-SHA256 signature from the request body
signature = hmac.new(
API_SECRET.encode(),
body_json.encode(),
hashlib.sha256
).hexdigest()
# Make request
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json",
"X-Signature": signature,
}
response = requests.post(f"{BASE_URL}/v2/topics", headers=headers, data=body_json)
response.raise_for_status()
return response.json()
Example: GET request (Python)
For GET requests, sign the full URI path (including query string if present):
import hmac
import hashlib
import requests
def get_topic(topic_id: str) -> dict:
"""Get a specific topic from Zenzap with HMAC signature."""
# For GET requests, sign the URI path (including query string if any)
uri_path = f"/v2/topics/{topic_id}"
# Create HMAC-SHA256 signature from the URI path
signature = hmac.new(
API_SECRET.encode(),
uri_path.encode(),
hashlib.sha256
).hexdigest()
# Make request
headers = {
"Authorization": f"Bearer {API_KEY}",
"X-Signature": signature,
}
response = requests.get(f"{BASE_URL}/v2/topics/{topic_id}", headers=headers)
response.raise_for_status()
return response.json()
Our API documentation tools cannot automatically generate HMAC signatures. You will need to calculate this manually or use a tool like Postman with pre-request scripts.