API REFERENCE
Discover/check exact candidate appointment windows
/api/v1/businesses/{id}/availabilityCandidate windows are returned unchanged and in submitted order. Discovery requires gap_seconds, window length=duration+gap; zero is allowed. Both locks default false and travel/full-service fit is strict. Queries save tentative alternatives, not saved route changes. First conflicting confirmation wins; max24h/passed-window expiry. Current implementation examines all eligible business vans; service zones are deferred. Integration permission: availability.query. Administrator membership grants management access only to this business.
Authentication
Authorized business administrator session, or a business API key with availability.query.
Parameters
| Parameter | In | Type | Description |
|---|---|---|---|
idRequired | path | string | Authorized business context. Never inferred from client record IDs.Format: uuid |
Request
| Field | Type | Description & constraints |
|---|---|---|
startRequired | string | RFC3339 UTC instant or explicit offset; business wall times are resolved separately.Format: date-time |
endRequired | string | RFC3339 UTC instant or explicit offset; business wall times are resolved separately.Format: date-time |
locationRequired | object | Service or record location, using latitude/longitude in decimal degrees. |
duration_secondsRequired | integer | Time needed to do the work, excluding travel, in seconds.Min: 1 |
gap_seconds | integer | Extra appointment-window allowance in seconds; discovery window length is duration plus gap.Min: 0 |
candidate_windows | array<object> | Alternative windows for one order. Check availability without changing the submitted boundaries. |
schedule_lock | boolean | Preserve existing planned start times and relative stop order. Defaults to false. |
assignment_lock | boolean | Preserve existing vehicle/driver assignments. Defaults to false. |
location fields
| Field | Type | Description & constraints |
|---|---|---|
location.latitudeRequired | number | Latitude in decimal degrees, from -90 to 90.Min: -90 · Max: 90 |
location.longitudeRequired | number | Longitude in decimal degrees, from -180 to 180.Min: -180 · Max: 180 |
candidate_windows[] fields
| Field | Type | Description & constraints |
|---|---|---|
candidate_windows.startRequired | string | RFC3339 UTC instant or explicit offset; business wall times are resolved separately.Format: date-time |
candidate_windows.endRequired | string | RFC3339 UTC instant or explicit offset; business wall times are resolved separately.Format: date-time |
Example JSON body
{
"start": "2026-11-02T08:00:00Z",
"end": "2026-11-02T16:00:00Z",
"location": {
"latitude": 52.2297,
"longitude": 21.0122
},
"duration_seconds": 1800,
"gap_seconds": 1800,
"schedule_lock": false,
"assignment_lock": false
}Request schema
{
"type": "object",
"properties": {
"start": {
"type": "string",
"format": "date-time",
"description": "RFC3339 UTC instant or explicit offset; business wall times are resolved separately."
},
"end": {
"type": "string",
"format": "date-time",
"description": "RFC3339 UTC instant or explicit offset; business wall times are resolved separately."
},
"location": {
"$ref": "#/components/schemas/Location"
},
"duration_seconds": {
"type": "integer",
"minimum": 1
},
"gap_seconds": {
"type": "integer",
"minimum": 0
},
"candidate_windows": {
"type": "array",
"items": {
"type": "object",
"properties": {
"start": {
"type": "string",
"format": "date-time",
"description": "RFC3339 UTC instant or explicit offset; business wall times are resolved separately."
},
"end": {
"type": "string",
"format": "date-time",
"description": "RFC3339 UTC instant or explicit offset; business wall times are resolved separately."
}
},
"required": [
"start",
"end"
]
}
},
"schedule_lock": {
"type": "boolean"
},
"assignment_lock": {
"type": "boolean"
}
},
"required": [
"start",
"end",
"location",
"duration_seconds"
]
}Example request
Replace synthetic identifiers and credentials. Example dates, coordinates, revisions, and IDs are not production defaults. Read the workflow guide before making a write.
curl --request POST 'https://route-api.okok.space/api/v1/businesses/11111111-1111-4111-8111-111111111111/availability' \
--header 'Authorization: Bearer REPLACE_WITH_TOKEN' \
--header 'Content-Type: application/json' \
--data '{"start":"2026-11-02T08:00:00Z","end":"2026-11-02T16:00:00Z","location":{"latitude":52.2297,"longitude":21.0122},"duration_seconds":1800,"gap_seconds":1800,"schedule_lock":false,"assignment_lock":false}'Responses
Examples illustrate the documented shape; optional fields and current state can differ. JSON extraction/body-limit errors may be plain text.
200 · Successful response
application/json
| Field | Type | Description & constraints |
|---|---|---|
group_id | string | Identifier linking mutually alternative windows for one prospective order. |
windows | array<object> | Resource-specific value; see the related workflow and schema. |
windows[] fields
| Field | Type | Description & constraints |
|---|---|---|
windows.startRequired | string | RFC3339 UTC instant or explicit offset; business wall times are resolved separately.Format: date-time |
windows.endRequired | string | RFC3339 UTC instant or explicit offset; business wall times are resolved separately.Format: date-time |
windows.availableRequired | boolean | Whether full service and travel can fit within this candidate window. |
windows.reservation_id | string | null | Temporary offer identifier; use it to confirm one booking. |
windows.expires_at | string | null | Latest instant this temporary offer or session remains valid. |
windows.reason | string | Required free-text explanation when work cannot be completed. |
Illustrative response
{
"group_id": "example",
"windows": [
{
"start": "2026-11-02T08:00:00Z",
"end": "2026-11-02T16:00:00Z",
"available": false,
"reservation_id": "example",
"expires_at": "2026-11-02T09:00:00Z",
"reason": "The customer could not provide access."
}
]
}Response schema
{
"type": "object",
"properties": {
"group_id": {
"type": "string"
},
"windows": {
"type": "array",
"items": {
"type": "object",
"properties": {
"start": {
"type": "string",
"format": "date-time",
"description": "RFC3339 UTC instant or explicit offset; business wall times are resolved separately."
},
"end": {
"type": "string",
"format": "date-time",
"description": "RFC3339 UTC instant or explicit offset; business wall times are resolved separately."
},
"available": {
"type": "boolean"
},
"reservation_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"expires_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"description": "RFC3339 UTC instant or explicit offset; business wall times are resolved separately."
},
{
"type": "null"
}
]
},
"reason": {
"type": "string"
}
},
"required": [
"start",
"end",
"available"
]
}
}
}
}401 · Missing/invalid/revoked token
application/json
| Field | Type | Description & constraints |
|---|---|---|
errorRequired | object | Resource-specific value; see the related workflow and schema. |
error fields
| Field | Type | Description & constraints |
|---|---|---|
error.codeRequired | validation | unauthorized | not_found | conflict | unavailable | rate_limited | Private activation or recovery code supplied to the driver. |
error.messageRequired | string | Resource-specific value; see the related workflow and schema. |
Illustrative response
{
"error": {
"code": "unauthorized",
"message": "Missing/invalid/revoked token"
}
}Response schema
{
"$ref": "#/components/schemas/Error"
}403 · Business membership or required API-key scope denied
application/json
| Field | Type | Description & constraints |
|---|---|---|
errorRequired | object | Resource-specific value; see the related workflow and schema. |
error fields
| Field | Type | Description & constraints |
|---|---|---|
error.codeRequired | validation | unauthorized | not_found | conflict | unavailable | rate_limited | Private activation or recovery code supplied to the driver. |
error.messageRequired | string | Resource-specific value; see the related workflow and schema. |
Illustrative response
{
"error": {
"code": "unauthorized",
"message": "Business membership or required API-key scope denied"
}
}Response schema
{
"$ref": "#/components/schemas/Error"
}404 · Record not found in authorized business
application/json
| Field | Type | Description & constraints |
|---|---|---|
errorRequired | object | Resource-specific value; see the related workflow and schema. |
error fields
| Field | Type | Description & constraints |
|---|---|---|
error.codeRequired | validation | unauthorized | not_found | conflict | unavailable | rate_limited | Private activation or recovery code supplied to the driver. |
error.messageRequired | string | Resource-specific value; see the related workflow and schema. |
Illustrative response
{
"error": {
"code": "not_found",
"message": "Record not found in authorized business"
}
}Response schema
{
"$ref": "#/components/schemas/Error"
}409 · Duplicate identifier, stale revision, expired reservation, protected publication or unavailable capacity
application/json
| Field | Type | Description & constraints |
|---|---|---|
errorRequired | object | Resource-specific value; see the related workflow and schema. |
error fields
| Field | Type | Description & constraints |
|---|---|---|
error.codeRequired | validation | unauthorized | not_found | conflict | unavailable | rate_limited | Private activation or recovery code supplied to the driver. |
error.messageRequired | string | Resource-specific value; see the related workflow and schema. |
Illustrative response
{
"error": {
"code": "conflict",
"message": "Duplicate identifier, stale revision, expired reservation, protected publication or unavailable capacity"
}
}Response schema
{
"$ref": "#/components/schemas/Error"
}422 · Domain validation rejected the operation
application/json
| Field | Type | Description & constraints |
|---|---|---|
errorRequired | object | Resource-specific value; see the related workflow and schema. |
error fields
| Field | Type | Description & constraints |
|---|---|---|
error.codeRequired | validation | unauthorized | not_found | conflict | unavailable | rate_limited | Private activation or recovery code supplied to the driver. |
error.messageRequired | string | Resource-specific value; see the related workflow and schema. |
Illustrative response
{
"error": {
"code": "validation",
"message": "Domain validation rejected the operation"
}
}Response schema
{
"$ref": "#/components/schemas/Error"
}503 · Required persistence, map/routing or other infrastructure unavailable
application/json
| Field | Type | Description & constraints |
|---|---|---|
errorRequired | object | Resource-specific value; see the related workflow and schema. |
error fields
| Field | Type | Description & constraints |
|---|---|---|
error.codeRequired | validation | unauthorized | not_found | conflict | unavailable | rate_limited | Private activation or recovery code supplied to the driver. |
error.messageRequired | string | Resource-specific value; see the related workflow and schema. |
Illustrative response
{
"error": {
"code": "unavailable",
"message": "Required persistence, map/routing or other infrastructure unavailable"
}
}Response schema
{
"$ref": "#/components/schemas/Error"
}