Authentication
Every request under /rest/v1 needs an organization API key. Most routes are read-only. Keys can also send a single-guest reminder when they include reminders:send.
Create a key
Owners and Organization Admins create keys from My organization. The secret is a JWT and is shown once. WeHabit stores only a SHA-256 hash of that token.
Each key is scoped to one organization and is issued with events:read, guests:read, and reminders:send. It can list events and guests, and send one reminder email to one guest registration. It cannot create events, update or delete guest data, or email all guests at once.
You can set an expiration date. The API rejects the key after that moment. Revoke turns a key off immediately, even if it has not expired. Other Owners and Organization Admins can see who created a key, when it was created, and when it expires.
Send the key
Authorization: Bearer <JWT>
Accept: application/json
Content-Type is not required on GET requests. For POST (guest reminder), send Content-Type: application/json. X-Request-ID is optional. When you send a short id (letters, numbers, ., _, or -, up to 128 characters), the API echoes it on the response.
Limits
Each key allows 60 requests per minute. The window is one clock minute. When the limit is exceeded the API responds with 429 and a Retry-After header.
Error shape
Every error uses this body:
{
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication is required."
}
}
| Status | Code | When |
|---|---|---|
| 401 | UNAUTHORIZED | Missing, malformed, invalid, or expired JWT, or a revoked key. |
| 403 | FORBIDDEN | The key is valid but does not include the scope the route requires. |
| 400 | INVALID_REQUEST | A query parameter or JSON field is invalid. details names each field. |
| 404 | NOT_FOUND | The route does not exist, or a referenced record (such as a branch or guest) was not found in this organization. |
| 405 | METHOD_NOT_ALLOWED | The route exists but the HTTP method is not allowed. The response includes Allow. |
| 409 | EVENT_DRAFT | The resource exists but the event must be published first (guest reminder). |
| 429 | RATE_LIMIT_EXCEEDED | The key exceeded 60 requests in the current minute. retry_after is seconds. |
| 500 | INTERNAL | The API could not complete the request. |