← Back to Surveyz
For Developers & Enterprises

Programmatic survey infrastructure, built for South Africa

Integrate the Surveyz REST API into your own products and workflows. POPIA-compliant, audit-logged, signed webhooks, and a full legal package your procurement team can review before signing.

Read the API reference Talk to sales

What you can build

The Enterprise plan unlocks the full programmatic surface area of Surveyz. Use it to embed surveys, ingest responses in real-time, or pipe data into your own analytics stack.

REST API

Surveys, questions, responses, exports — fully CRUD-able under /api/ with versioned URL aliases.

Signed Webhooks

HMAC-SHA256 signed event delivery with replay protection, exponential backoff and auto-pause on failure.

Scoped API Keys

Read-only or full access; optional IP allow-list per key. Revoke or rotate at any time.

Audit Log

Every API call is logged with method, path, status, latency, IP, and trace ID — queryable from the developer portal.

Rate-limit Headers

Standards-compliant RateLimit-* and Retry-After headers; RFC 7807 Problem Details on errors.

Direct Support

Enterprise customers get a named contact, faster response SLAs, and access to [email protected].

Legal package — review before you buy

Procurement and legal teams can review the entire B2B legal stack up front. Each document is a standalone HTML page with a Download PDF button (uses your browser's print-to-PDF) so you can attach it to your purchase records.

30-second quick-start

Pass your API key in the X-Api-Key header on every request. Below are the same two operations in three languages.

# List your surveys
curl https://surveyz.co.za/api/surveys \
  -H "X-Api-Key: sr_your_key_here"

# Submit a webhook subscription
curl -X POST https://surveyz.co.za/api/webhooks \
  -H "X-Api-Key: sr_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://your-server.com/hooks","events":"response.submitted"}'
// npm install node-fetch  (or use built-in fetch on Node 18+)
const KEY = process.env.SURVEYZ_API_KEY;

// List surveys
const r1 = await fetch('https://surveyz.co.za/api/surveys', {
    headers: { 'X-Api-Key': KEY }
});
const surveys = await r1.json();

// Subscribe to webhooks
const r2 = await fetch('https://surveyz.co.za/api/webhooks', {
    method: 'POST',
    headers: { 'X-Api-Key': KEY, 'Content-Type': 'application/json' },
    body: JSON.stringify({
        url:    'https://your-server.com/hooks',
        events: 'response.submitted'
    })
});
const { secret } = await r2.json(); // ← save once
import os, requests

key = os.environ['SURVEYZ_API_KEY']
headers = {'X-Api-Key': key}

# List surveys
surveys = requests.get('https://surveyz.co.za/api/surveys',
                       headers=headers).json()

# Subscribe to webhooks
resp = requests.post('https://surveyz.co.za/api/webhooks',
                     headers={**headers, 'Content-Type': 'application/json'},
                     json={'url': 'https://your-server.com/hooks',
                           'events': 'response.submitted'})
secret = resp.json()['secret']  # ← save once
using var http = new HttpClient { BaseAddress = new("https://surveyz.co.za") };
http.DefaultRequestHeaders.Add("X-Api-Key", Environment.GetEnvironmentVariable("SURVEYZ_API_KEY"));

// List surveys
var surveys = await http.GetFromJsonAsync<List<Survey>>("/api/surveys");

// Subscribe to webhooks
var resp = await http.PostAsJsonAsync("/api/webhooks", new {
    url    = "https://your-server.com/hooks",
    events = "response.submitted"
});
var body = await resp.Content.ReadFromJsonAsync<WebhookResponse>();
// body.Secret — save once

Common questions from procurement

Where is data hosted?

Production data is stored in Microsoft Azure South Africa North (Johannesburg). See the DPA for the full sub-operator list and cross-border transfer mechanism.

Are you POPIA compliant?

Yes. Our POPIA Compliance page describes our obligations as a Responsible Party. The DPA covers our Operator obligations when you process Personal Information through our API on your customers' behalf.

What rate limits apply?

300 requests per minute per authenticated caller (per API key or per JWT subject). Anonymous limit is 60 req/min. Bursts above this return HTTP 429 with a Retry-After header. Higher limits available on request — contact sales.

How are webhook payloads secured?

Each delivery is signed with HMAC-SHA256 over {timestamp}.{body} using your subscription's secret. Headers X-Surveyz-Signature and X-Surveyz-Timestamp let you verify authenticity and reject replays. Failed deliveries retry at 1m → 5m → 30m → 2h → 8h, then auto-pause.

How do we revoke a compromised key?

Rotate or revoke from the Developer Portal. Revocation is immediate. Keys are stored as SHA-256 hashes — we never have access to plaintext after generation.

Do you support read-only API keys?

Yes. Set scope to read_only in Key Settings. Mutating verbs (POST/PUT/PATCH/DELETE) return 403 immediately. Useful for analytics integrations that should never write back.

Can we restrict an API key to specific IP addresses?

Yes. Add a comma-separated list of IPv4 addresses in Key Settings. Requests from unlisted IPs return 403.

How do we get an audit trail of API activity?

Every API call is logged to ApiAuditLogs: method, path, status, latency, IP, user agent, auth method (apikey/jwt). Query via GET /api/developer/audit-logs with filters on method, status, time range.

Ready to evaluate?

Send your team's procurement questions and we'll respond within one business day. We're happy to share signed PDFs of the legal package, walk through the API on a call, or put you in touch with existing Enterprise customers.