Base URL
/v1. Send request bodies as JSON with Content-Type: application/json. Every response body is JSON, except 204 No Content responses, which have no body. Timestamps are ISO 8601 strings in UTC.
wede is hosted in the European Union by default. Where local regulation requires in-country data residency, a dedicated regional instance is available by agreement.
Authentication
wede accepts two credentials. Use the one that matches where your code runs.API key
Header
x-wede-api-key. For your servers and backend jobs. Never put it in a browser, a mobile app or any bundle you ship to users.Session token
Header
Authorization: Bearer <token>. Returned by POST /v1/auth/login. For people signing in to your apps and to the wede dashboard.API key
An API key is the credential for your integration. It can:
Managing zones, teams, dispatch, missions, users, API keys and your event type catalog requires a session token of a user whose role grants it. An API key calling those endpoints receives
403 forbidden.
wede stores only a SHA-256 hash of each key, so a key is shown in full only once, when it is created or rotated. A user with the api_keys:manage permission rotates a key with POST /v1/tenant/api-keys/rotate: the new key works immediately and the previous one keeps working for a grace period (24 hours unless grace_hours is set), so you can roll it out without downtime.
Session token
Calling the API from a browser
The API accepts cross-origin requests from any origin. It authenticates only with thex-wede-api-key and Authorization headers, never with cookies, so a web app can call it directly with the signed-in user’s session token. Never put an API key in a browser: keep keys on your servers.
Environments
Each API key belongs to one environment, and everything it creates is stored with that environment.- An API key reads only its own environment. A session reads production by default and can pass
environment=sandboxonGET /v1/events,GET /v1/events/:event_idandGET /v1/sync/status. - The same
idempotency_keycan exist once in production and once in sandbox. - Sandbox results are recorded on the event and in its lifecycle. Lifecycle notes of simulated steps start with
sandbox:. - Webhook deliveries carry
"environment": "sandbox"or"environment": "production", so one endpoint can tell them apart. - With a sandbox key you can change a zone’s simulated state with
POST /v1/sandbox/simulate-connectivityorPOST /v1/connectivity/report. The real state of the zone is never touched.
Errors
Errors use standard HTTP status codes and a JSON body:
Codes you will meet across the API:
Each endpoint page lists every status and code that endpoint returns.
Retries and rate limiting
Retry5xx responses and network errors with exponential backoff. For events and sync batches, always resend the same idempotency_key: a request that already reached wede returns 409 duplicate_event (or duplicate in a batch) instead of creating a second event.
Requests made with an API key are limited per tenant and per minute. The limit is the one set for your tenant or, if none is set, the one of your plan; the default is 500 requests per minute. All the keys of your tenant share it. Every API key response carries:
Above the limit, wede answers
429 with a Retry-After header (seconds) and this body:
retry_after_seconds before retrying, and resend the same idempotency_key. For bursts of offline operations, send them in one sync batch of up to 500 events: a batch counts as one request.
POST /v1/auth/login returns 429 account_locked after repeated failed sign-ins.
Idempotency
POST /v1/events and every event in POST /v1/sync/batch require an idempotency_key (1 to 128 characters). wede stores each key once per tenant and environment:
- The same key on
POST /v1/eventsreturns409 duplicate_event. - The same key in a sync batch returns
result: "duplicate"with theevent_idof the event already stored, whether that event arrived online or in an earlier batch.
X-Wede-Delivery, which stays the same across retries of one delivery. Use it to discard deliveries you have already processed.
Pagination
GET /v1/events uses cursor pagination:
- Call it with an optional
limit(default 50, maximum 200). - If the response has a non-null
next_cursor, pass it ascursorto get the next page. - Stop when
next_cursorisnull.
total_count is the number of events that match your filters across all pages. Keep the same filters while you page. Cursors are opaque: do not build or change them.
Other list endpoints (GET /v1/webhooks, GET /v1/catalog, GET /v1/catalog/equipment, GET /v1/connectivity/status) return every item in one response.
