Guides
Server Data API
Send people, companies and events from your own backend.
Keys
Create a server key in Whazzup under Settings → Data API. The key is shown once, stored hashed and can be rotated or revoked at any time. Keep it on your server only.
Endpoints
Base URL is https://whazzup.io/api/public/data/v1. All requests need Authorization: Bearer wz_… (or X-Api-Key: wz_…).
| Endpoint | Body | Response |
|---|---|---|
| GET /whoami | – | { ok, workspace: { id, name }, key: { name } } |
| POST /people | externalUserId or email (one required), name, company, attributes | { person: { id } } |
| GET /people/:id | – | { person } by internal ID or external user ID |
| POST /companies | externalId or name, plus plan, size, website, industry | { company: { id } } |
| POST /events | externalUserId or email, name, properties, pageUrl | { ok: true } |
People are matched by externalUserId first, then by email; an existing person is updated, otherwise created. Attributes are simple values (string, number, boolean, null) and merge into the existing attributes. Events require a person who has visited the widget at least once; otherwise the API answers no_visitor.
Examples
curl -X POST https://whazzup.io/api/public/data/v1/people \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"externalUserId":"42","email":"ada@example.com","attributes":{"plan":"pro","monthlyValue":49},"company":{"externalId":"acme","name":"Acme Inc","plan":"business","size":120}}'curl -X POST https://whazzup.io/api/public/data/v1/events \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"externalUserId":"42","name":"invoice_failed","properties":{"amount":49}}'Rate limits
- 600 requests per minute per API key, for reads and writes separately.
- 30 authentication attempts per minute per sender – this slows down key guessing.
- When limited, the API answers
429 rate_limitedwith aRetry-Afterheader. Wait that many seconds and retry.
Errors
| identifier_required | 400 | Send externalUserId or email so the record can be matched. |
| insufficient_data | 400 | A new person needs at least a name, an email or one attribute. |
| invalid_input / invalid_json | 400 | The body is not valid JSON or fails validation. |
| person_not_found | 404 | No person matches the given externalUserId or email. |
| no_visitor | 409 | The person has never opened the widget, so events cannot be attached yet. |
| rate_limited | 429 | Slow down and honor the Retry-After header. |
| save_failed | 500 | Temporary server problem – safe to retry the same request. |
Fixing 401 unauthorized
Base URL is https://whazzup.io/api/public/data/v1. Send the key as Authorization: Bearer wz_… or X-Api-Key: wz_…. Server-to-server calls are allowed from any IP; there is no origin or IP allowlist on this API. Identity verification only applies to the browser widget, never to the Data API.
A key looks like wz_XXXXXXXX_<64 hex chars> and is shown once when created. The public workspace ID used by widget.js is not a Data API key.
curl https://whazzup.io/api/public/data/v1/whoami \
-H "Authorization: Bearer $WHAZZUP_API_KEY"Every 401 response carries a reason and a hint:
missing_credentials- No key was sent. Add the header Authorization: Bearer wz_… (or X-Api-Key).malformed_key- The value is not a Data API key. Use the wz_XXXXXXXX_… key, not the public widget workspace ID.unknown_key- No active key matches. The key was rotated or copied incompletely – create a new one.revoked_key- The key was revoked. Create a new key under Settings → Data API.
