Skip to main content
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

  1. 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)
  2. Calculate HMAC-SHA256 of the payload using your API secret
  3. 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.