Developers
Ingest guide
Everything you need to wire your CRM, CI pipeline, AI agents, or internal tools into WePeople. Pair this guide with the API reference for per-endpoint contracts.
Concepts
The Ingest API is private and per-organization. You create one or more developer apps inside an organization; each app owns its own API keys, event-type whitelist, and synthetic integration connection. Events show up on the monitoring dashboard as custom:<app-slug>, side by side with Slack, GitHub, and Jira.
Two primitives: events (discrete timeline rows) and snapshots (point-in-time gauges on the user strip).
Authentication
Authenticate every request with a bearer token. Generate keys from Organization → Developer → New key. Keys are prefixed with wp_live_ and shown once.
Smoke-test with GET /api/v1/ingest/ping. See Auth & headers for idempotency and CORS details.
Authorization: Bearer wp_live_9f3c3e4c1e9b4b2d9c1e3f4b2c3d4e5fIdentifying workers
Every event and snapshot belongs to a worker. The actor object accepts three identifiers; the server resolves in order:
workerId— existing WePeople worker id.externalId— your system’s stable id (recommended). Unique per app.email— match against the org directory.
When nothing matches, WePeople auto-provisions a worker and links it to the app’s custom:<slug> connection. Optional displayName sets the name on create.
Events
Events are batched — up to 100 per request, body ≤ 1 MB. Each entry needs eventType (whitelisted), category, and actor. Optional timestamp (ISO 8601), duration (0–86400 seconds), and metadata(≤ 16 KB JSON).
Full field reference: POST events.
{
"events": [
{
"eventType": "deploy.shipped",
"category": "CODE_CHANGE",
"timestamp": "2026-04-19T12:05:00Z",
"actor": { "externalId": "eng-17" },
"duration": 612,
"metadata": {
"service": "checkout-api",
"sha": "3c4d8a1",
"env": "production"
}
}
]
}The response includes accepted, rejected, and a per-row breakdown. Partial success yields 207 — resend only the rejected indices.
Snapshots
A snapshot replaces the previous snapshot for the same (worker, snapshotType) pair. The user strip renders up to four metrics per app. Metrics may be plain numbers, short strings, or rich objects with value, unit, and label.
See POST snapshots.
{
"snapshotType": "oncall_queue",
"actor": { "email": "alex@acme.com" },
"metrics": {
"active": 2,
"waiting": { "value": 5, "unit": "count", "label": "queued" },
"p95_ack": { "value": 3.4, "unit": "minutes", "label": "p95 ack" }
}
}Idempotency
Add an Idempotency-Key header (≤ 200 chars) on every write. The first response for a given key is cached for ten minutes and replayed verbatim on retry — safe for at-least-once queues and cron jobs.
The TypeScript SDK generates one per call by default. Override when you want your queue to dedupe:
await client.ingestEvents(events, {
idempotencyKey: `${jobId}:${attempt}`,
});Rate limits & caps
Three independent budgets apply:
- Per key: 60 req/s (sliding window).
- Per organization: 600 req/s aggregate across all keys.
- Monthly events: plan cap
maxEventsPerMonth. Returnsquota_exceeded(402) when exhausted.
On rate_limited (429), respect Retry-After and X-RateLimit-* headers. The SDK retries with exponential backoff and jitter.
Errors
Every error is JSON with a stable code, human-readable message, requestId, and docsUrl pointing to error codes.
{
"error": {
"code": "forbidden_event_type",
"message": "eventType 'deploy.shipped' is not in this app's whitelist.",
"requestId": "req_01HP3K5V4J3M9NVT8XZKQ9YQ2E",
"docsUrl": "https://wepeople.app/docs/reference/errors"
}
}Handle distinctly: invalid_key, quota_exceeded, rate_limited, forbidden_event_type, and invalid_body. Transient failures (internal_error) are retryable.
Security
Keys are bcrypt-hashed, shown once, and revocable from the Developer tab. All writes use TLS. Metadata is stored as JSONB and is retrievable only within the owning organization. If a key leaks, revoke immediately — revocation takes effect on the next auth lookup (≤ 60 seconds with the current cache).
Ingest endpoints allow browser CORS for Authorization and Idempotency-Key; still treat keys as server-side secrets in production.