REST endpoints for weather in ServFlo: 6 operations with parameters, request and response fields, permissions and curl examples.
Base URL: https://app.servflo.ai/api. Every call needs Authorization: Bearer sfk_… (Authentication); {organizationId} ($ORGANIZATION_ID in the examples) is your business's id.
GET /organizations/{organizationId}/weather/settings
Weather-aware scheduling settings: whether the office is alerted when an outdoor visit's forecast turns bad, how many days ahead, the units people see, where forecasts come from and whether the business address has a map location. Read-only.
Alert the office when an outdoor visit's forecast turns bad.
alertDaysAhead
integer
How many days ahead visits are watched for alerts.
unitsSetting
enum or null
The chosen units; null = by the business's country. One of imperial, metric.
units
enum
How people see it: imperial (°F, mph, in) or metric (°C, km/h, mm). Numbers in answers are always imperial. One of imperial, metric.
mode
enum
Where forecasts come from: nws (US National Weather Service, about 7 days), open-meteo (16 days), fake (scripted) or off. One of nws, open-meteo, fake, off.
hasBusinessLocation
boolean
The business address has a map location (the dispatch board's daily forecast).
Turn weather alerts on or off, set how many days ahead (1-7) outdoor visits are watched, and the units (imperial, metric, or null for the business's country). Which work is outdoor and its limits are set per service type (PATCH /service-types/{serviceTypeId}: weatherSensitive and the weather limits). Owners and admins.
Permission
organization.manage (Owner, Admin)
Risk
write, OAuth scope servflo.write. Write: creates or changes records inside the business; nothing leaves it.
Alert the office when an outdoor visit's forecast turns bad.
alertDaysAhead
integer
How many days ahead visits are watched for alerts.
unitsSetting
enum or null
The chosen units; null = by the business's country. One of imperial, metric.
units
enum
How people see it: imperial (°F, mph, in) or metric (°C, km/h, mm). Numbers in answers are always imperial. One of imperial, metric.
mode
enum
Where forecasts come from: nws (US National Weather Service, about 7 days), open-meteo (16 days), fake (scripted) or off. One of nws, open-meteo, fake, off.
hasBusinessLocation
boolean
The business address has a map location (the dispatch board's daily forecast).
GET /organizations/{organizationId}/jobs/{jobId}/weather
The forecast at the job's property and each open visit checked against its service type's limits (GOOD, WATCH, BAD or UNKNOWN, with reasons), whether the job plans around the weather, and the next clear days for its next open visit. Use it before booking or moving outdoor work; to move a visit for the weather call POST /jobs/{jobId}/weather/reschedule. Technicians: their own jobs. Read-only.
The job plans around the weather (alerts, the banner).
source
enum
job = the job's own switch; serviceType = its service type is outdoor work; none = neither. One of job, serviceType, none.
serviceTypeName
string or null
limits
object
limits.maxRainChance
number
BAD at or above this chance of rain (%).
limits.maxWindMph
number
BAD at or above this wind (gusts count at 75 %).
limits.minTempF
number or null
BAD below this; null = no limit.
limits.maxTempF
number or null
BAD above this; null = no limit.
units
enum
How people see it: imperial (°F, mph, in) or metric (°C, km/h, mm). Numbers in answers are always imperial. One of imperial, metric.
hasLocation
boolean
The property has a map location (needed for a forecast).
forecastError
string or null
fetchedAt
string or null
forecastThrough
string or null
The last day the forecast reaches.
days
array of object
The daily forecast at the property from today.
days[].date
string
days[].condition
enum
The worst sky between 07:00 and 19:00. One of clear, partly_cloudy, cloudy, fog, drizzle, rain, snow, storm.
days[].highF
number
days[].lowF
number
days[].rainPct
number
Highest chance of precipitation between 07:00 and 19:00.
days[].windMph
number
days[].gustMph
number or null
days[].precipIn
number or null
days[].hourCount
integer
visits
array of object
visits[].visitId
string
visits[].scheduledDate
string or null
visits[].scheduledTime
string or null
visits[].durationMinutes
integer
visits[].status
string
visits[].assessment
object or null
Null when the visit is not scheduled.
visits[].assessment.status
enum
Good: within every limit; WATCH: close to a limit; BAD: past a limit, or thunderstorms or snow; UNKNOWN: the forecast does not reach this time yet (or no map location). One of GOOD, WATCH, BAD, UNKNOWN.
visits[].assessment.summary
string
One line, in the business's units.
visits[].assessment.reasons
array of object
visits[].assessment.rainPct
number or null
visits[].assessment.windMph
number or null
visits[].assessment.gustMph
number or null
visits[].assessment.lowF
number or null
visits[].assessment.highF
number or null
visits[].assessment.condition
enum or null
One of clear, partly_cloudy, cloudy, fog, drizzle, rain, snow, storm.
visits[].assessment.hours
array of object
The forecast hours the visit covers.
suggestions
array of object
The next clear days for the job's next open visit (up to 3), as far as the forecast reaches.
suggestions[].date
string
A day the same visit (same time and length) would be GOOD.
GET /organizations/{organizationId}/weather/forecast
For booking a job that does not exist yet: the daily forecast at a property, a day and time (and length, default the service type's) checked against the service type's limits, and the next clear days after it. Without a date, only the forecast and the next clear days from today. Find the property with GET /customers/{customerId}. Read-only.
How people see it: imperial (°F, mph, in) or metric (°C, km/h, mm). Numbers in answers are always imperial. One of imperial, metric.
hasLocation
boolean
forecastError
string or null
forecastThrough
string or null
days
array of object
days[].date
string
days[].condition
enum
The worst sky between 07:00 and 19:00. One of clear, partly_cloudy, cloudy, fog, drizzle, rain, snow, storm.
days[].highF
number
days[].lowF
number
days[].rainPct
number
Highest chance of precipitation between 07:00 and 19:00.
days[].windMph
number
days[].gustMph
number or null
days[].precipIn
number or null
days[].hourCount
integer
assessment
object or null
The asked slot checked; null without a date.
assessment.status
enum
Good: within every limit; WATCH: close to a limit; BAD: past a limit, or thunderstorms or snow; UNKNOWN: the forecast does not reach this time yet (or no map location). One of GOOD, WATCH, BAD, UNKNOWN.
assessment.summary
string
One line, in the business's units.
assessment.reasons
array of object
assessment.reasons[].kind
enum
One of rain, wind, cold, heat, storm, snow.
assessment.reasons[].level
enum
One of BAD, WATCH.
assessment.reasons[].text
string
assessment.reasons[].value
number or null
The number behind it, imperial: rain %, wind mph, low or high °F; null for storms and snow.
assessment.reasons[].gustMph
number or null
Wind only: the gusts, when worth naming.
assessment.rainPct
number or null
assessment.windMph
number or null
assessment.gustMph
number or null
assessment.lowF
number or null
assessment.highF
number or null
assessment.condition
enum or null
One of clear, partly_cloudy, cloudy, fog, drizzle, rain, snow, storm.
assessment.hours
array of object
The forecast hours the visit covers.
assessment.hours[].t
string
Local hour at the property, YYYY-MM-DDTHH:00.
assessment.hours[].tempF
number
assessment.hours[].rainPct
number
Chance of precipitation, 0-100.
assessment.hours[].precipIn
number or null
assessment.hours[].windMph
number
assessment.hours[].gustMph
number or null
assessment.hours[].condition
enum
One of clear, partly_cloudy, cloudy, fog, drizzle, rain, snow, storm.
suggestions
array of object
suggestions[].date
string
A day the same visit (same time and length) would be GOOD.
GET /organizations/{organizationId}/weather/schedule
For the dispatch board and calendar: the daily forecast at the business's address for a date range (at most 31 days; forecasts reach about 7-16 days), and every weather-sensitive open visit in the range checked at its own property. Technicians: their own visits. Read-only.
How people see it: imperial (°F, mph, in) or metric (°C, km/h, mm). Numbers in answers are always imperial. One of imperial, metric.
hasBusinessLocation
boolean
days
array of object
The daily forecast at the business's address.
days[].date
string
days[].condition
enum
The worst sky between 07:00 and 19:00. One of clear, partly_cloudy, cloudy, fog, drizzle, rain, snow, storm.
days[].highF
number
days[].lowF
number
days[].rainPct
number
Highest chance of precipitation between 07:00 and 19:00.
days[].windMph
number
days[].gustMph
number or null
days[].precipIn
number or null
days[].hourCount
integer
visits
array of object
visits[].visitId
string
visits[].jobId
string
visits[].identifier
string
visits[].scheduledDate
string or null
visits[].scheduledTime
string or null
visits[].durationMinutes
integer
visits[].status
string
visits[].hasLocation
boolean
visits[].assessment
object or null
visits[].assessment.status
enum
Good: within every limit; WATCH: close to a limit; BAD: past a limit, or thunderstorms or snow; UNKNOWN: the forecast does not reach this time yet (or no map location). One of GOOD, WATCH, BAD, UNKNOWN.
visits[].assessment.summary
string
One line, in the business's units.
visits[].assessment.reasons
array of object
visits[].assessment.rainPct
number or null
visits[].assessment.windMph
number or null
visits[].assessment.gustMph
number or null
visits[].assessment.lowF
number or null
visits[].assessment.highF
number or null
visits[].assessment.condition
enum or null
One of clear, partly_cloudy, cloudy, fog, drizzle, rain, snow, storm.
POST /organizations/{organizationId}/jobs/{jobId}/weather/reschedule
Moves the job's visit (visitId, default its next scheduled one) to another day and optionally time, like any reschedule (reminders follow the new time). SENDS TO THE CUSTOMER when notifyCustomer is true (default): a text (else an email) saying the visit moved because of the weather; message replaces the default wording. Consent rules apply. Pick the day from GET /jobs/{jobId}/weather suggestions and confirm it with the person first. Returns the new slot and whether the customer was told.
Permission
jobs.write (Owner, Admin, Dispatcher)
Risk
sensitive, OAuth scope servflo.sensitive. Sensitive: moves money, deletes, sends or shows something to a customer, or grants or revokes access.
MCP tool
weather_reschedule (toolset scheduling)
Approval
Over MCP, this tool asks for your OK first (in the AI app when it supports it, otherwise in ServFlo). See Approvals.