Skip to content
Contents
Workspace data

Business hours and auto-replies

Two workspace settings that change how the platform answers on your behalf: when you are open, and what is said automatically when somebody writes. Both are evaluated on the SERVER, in the workspace's own timezone.

What is here

Four routes, and the scopes are not symmetrical — read them before wiring a role. The timezone these are evaluated in belongs to the workspace, not to the caller's browser.

EndpointScope
GET /v1/settings/business-hoursworkspace.read
PUT /v1/settings/business-hoursworkspace.manage
GET /v1/settings/auto-repliesautomations.manage
PUT /v1/settings/auto-repliesautomations.manage

Auto-replies take an automations scope

Reading the auto-replies requires automations.manage, not a read permission, because each toggle materialises a real automation. Business hours split the ordinary way instead: workspace.read to read, workspace.manage to write.

Business hours

GET/v1/settings/business-hoursPUT/v1/settings/business-hours
FieldTypeDescription
enabledbooleanWhether the week is applied at all.
timezonestringThe one clock involved. Everything here is evaluated in it.
daysobject<day, {from,to}[]>Open days only, each with one or more from/to windows.
state"open" | "closed"Open or closed right now, decided by the server.
suggested.daysobjectA starting week the API offers when nothing is configured yet.
curl
curl -X PUT https://whats.azzamkh.sa/api/v1/settings/business-hours \
  -H "Authorization: Bearer $WA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "enabled": true,
    "timezone": "Asia/Riyadh",
    "days": {
      "sun": [{ "from": "09:00", "to": "17:00" }],
      "mon": [{ "from": "09:00", "to": "17:00" }],
      "tue": [{ "from": "09:00", "to": "13:00" },
              { "from": "16:00", "to": "19:00" }]
    }
  }'

# 200 OK — "state" is the SERVER's answer, in the workspace timezone.
# {
#   "enabled": true,
#   "timezone": "Asia/Riyadh",
#   "days": { "sun": [...], "mon": [...], "tue": [...] },
#   "state": "open",
#   "suggested": { "days": { ... } }
# }

A closed day is an OMITTED day

Sending a day with an empty array is a 422. Send only the days that are open. Turning enabled off KEEPS the week rather than erasing it, and enabled: true with no open day is a 422 as well.

  • Never recompute state in a browser. A browser evaluates the week in ITS timezone, which is the exact mistake this setting exists to prevent — and the away automation reads the same hours server-side, so a locally derived badge would disagree with it.
  • Windows may repeat within a day, so a split shift is two entries on the same day rather than two settings.
  • suggested.days is a convenience, not the current value. Nothing is applied until you PUT it.

Welcome and away replies

GET/v1/settings/auto-repliesPUT/v1/settings/auto-replies

These are ordinary automations under the covers: each enabled toggle materialises one, with its own run log and the same loop protection. automation_id is how you find it.

FieldTypeDescription
welcome, awayobjectThe two replies. Send either, or both.
*.enabledbooleanWhether this reply is armed.
*.messagestring | nullThe text sent. Null when it has never been set.
*.automation_idstring | nullThe automation this toggle materialised, or null when it is off.
*.last_run_atstring | nullWhen it last fired.
business_hours_configuredbooleanWhether business hours exist. The away reply cannot be turned on without them.
curl
curl -X PUT https://whats.azzamkh.sa/api/v1/settings/auto-replies \
  -H "Authorization: Bearer $WA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "away": { "enabled": true, "message": "We are closed — back at 9am." }
  }'

# 200 OK
# {
#   "welcome": {
#     "enabled": false, "message": null,
#     "automation_id": null, "last_run_at": null
#   },
#   "away": {
#     "enabled": true, "message": "We are closed — back at 9am.",
#     "automation_id": "atm_...", "last_run_at": null
#   },
#   "business_hours_configured": true
# }

# Without business hours, turning "away" on is:
# 409 { "error": { "code": "BUSINESS_HOURS_NOT_CONFIGURED", ... } }

Errors that matter here

CodeHTTPWhen it happens
BUSINESS_HOURS_NOT_CONFIGURED409The away reply was turned on with no business hours configured. Disable the control for turning ON only — a switch frozen in the on position is a trap — and still handle the 409, because another tab can clear the hours between the page loading and the save landing.
VALIDATION_ERROR422An empty open day, enabled with no open day, or a malformed time.
FORBIDDEN403The caller holds neither the read nor the manage scope.

Every code and its status is on the errors page.