{"openapi":"3.1.0","info":{"title":"Spoke Dispatch (BYOK) API","version":"0.1.0","description":"Spoke Dispatch (BYOK) lets an AI assistant read your own Spoke Dispatch data through the Spoke Dispatch API with a key you supply (Spoke Dispatch API key). Read-only: 12 tools (list_plans, get_plan, list_plan_stops, get_stop, list_routes, get_route, list_route_stops, list_drivers, list_depots, list_unassigned_stops, search_stops, list_custom_stop_properties). The BYOK key travels with each...\n\nEvery operation is read-only or compute-only. The same tools are available over MCP (streamable HTTP) at https://byok-spoke.connectorbay.com/mcp.","contact":{"name":"Unify Dynamics LLC","email":"agent@connectorbay.com","url":"https://connectorbay.com/byok-spoke/docs"},"termsOfService":"https://connectorbay.com/byok-spoke/terms"},"servers":[{"url":"https://byok-spoke.connectorbay.com"}],"externalDocs":{"url":"https://connectorbay.com/byok-spoke/docs"},"security":[{"upstreamKey":[]}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"Optional. A Pro API key raises rate limits; no credentials are required."},"upstreamKey":{"type":"apiKey","in":"header","name":"X-Upstream-Key","description":"Your own key for the service this connector wraps (bring your own key). Used for that one call only; never stored, logged or cached."}},"schemas":{"Error":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object"}}}}},"paths":{"/v1/tools/list_plans":{"post":{"operationId":"list_plans","summary":"List delivery plans of the team with title, start date, depot, optimization state, drivers and routes. Filter by title o","description":"List delivery plans of the team with title, start date, depot, optimization state, drivers and routes. Filter by title or start date range. Use for \"Which delivery plans do I have for next week\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"title":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Exact plan title.","title":"Title"},"starts_from":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Only plans starting on or after this date (YYYY-MM-DD).","title":"Starts From"},"starts_until":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Only plans starting on or before this date (YYYY-MM-DD).","title":"Starts Until"},"max_page_size":{"anyOf":[{"maximum":20,"minimum":1,"type":"integer"},{"type":"null"}],"default":10,"description":"How many results per page (1 to 20).","title":"Max Page Size"},"page_token":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Token from nextPageToken of the previous answer to get the next page.","title":"Page Token"}},"title":"list_plansArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_plan":{"post":{"operationId":"get_plan","summary":"Get one delivery plan: title, start date, depot, whether it is distributed and optimized, and its drivers and routes. Us","description":"Get one delivery plan: title, start date, depot, whether it is distributed and optimized, and its drivers and routes. Use for \"Show plan abc123\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"plan_id":{"description":"Plan ID: the part after 'plans/' in a plan id such as plans/abc123.","maxLength":200,"title":"Plan Id","type":"string"}},"required":["plan_id"],"title":"get_planArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_plan_stops":{"post":{"operationId":"list_plan_stops","summary":"List the stops of a plan (10 per page at most) with address, type, activity, position, package count, ETA and delivery s","description":"List the stops of a plan (10 per page at most) with address, type, activity, position, package count, ETA and delivery state. Can filter by the recipient's external ID. Use for \"What stops are in plan abc123 and when will they be reached\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"plan_id":{"description":"Plan ID: the part after 'plans/' in a plan id such as plans/abc123.","maxLength":200,"title":"Plan Id","type":"string"},"external_id":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Only stops whose recipient external ID equals this.","title":"External Id"},"max_page_size":{"anyOf":[{"maximum":10,"minimum":1,"type":"integer"},{"type":"null"}],"default":10,"description":"How many results per page (1 to 10).","title":"Max Page Size"},"page_token":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Token from nextPageToken of the previous answer to get the next page.","title":"Page Token"}},"required":["plan_id"],"title":"list_plan_stopsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_stop":{"post":{"operationId":"get_stop","summary":"Get one stop of a plan with address, coordinates, type, notes, packages, recipient name, ETA and delivery details. Use f","description":"Get one stop of a plan with address, coordinates, type, notes, packages, recipient name, ETA and delivery details. Use for \"Show stop s1 of plan abc123\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"plan_id":{"description":"Plan ID: the part after 'plans/' in a plan id such as plans/abc123.","maxLength":200,"title":"Plan Id","type":"string"},"stop_id":{"description":"Stop ID: the part after 'stops/' in a stop id such as plans/abc/stops/xyz.","maxLength":200,"title":"Stop Id","type":"string"}},"required":["plan_id","stop_id"],"title":"get_stopArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_routes":{"post":{"operationId":"list_routes","summary":"List routes (one per driver) with title, stop count, driver, plan and progress flags. Filter by start date range. Use fo","description":"List routes (one per driver) with title, stop count, driver, plan and progress flags. Filter by start date range. Use for \"Which routes start this week and have they been started\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"starts_from":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Only routes starting on or after this date (YYYY-MM-DD).","title":"Starts From"},"starts_until":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Only routes starting on or before this date (YYYY-MM-DD).","title":"Starts Until"},"max_page_size":{"anyOf":[{"maximum":20,"minimum":1,"type":"integer"},{"type":"null"}],"default":20,"description":"How many results per page (1 to 20).","title":"Max Page Size"},"page_token":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Token from nextPageToken of the previous answer to get the next page.","title":"Page Token"}},"title":"list_routesArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_route":{"post":{"operationId":"get_route","summary":"Get one route: title, number of stops, assigned driver, plan and whether it is distributed, started or completed. Use fo","description":"Get one route: title, number of stops, assigned driver, plan and whether it is distributed, started or completed. Use for \"Is route abc123 completed\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"route_id":{"description":"Route ID: the part after 'routes/' in a route id such as routes/abc123.","maxLength":200,"title":"Route Id","type":"string"}},"required":["route_id"],"title":"get_routeArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_route_stops":{"post":{"operationId":"list_route_stops","summary":"List the stops of one route (10 per page at most) in driving order with address, ETA and delivery state. Use for \"What i","description":"List the stops of one route (10 per page at most) in driving order with address, ETA and delivery state. Use for \"What is the stop sequence for route abc123\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"route_id":{"description":"Route ID: the part after 'routes/' in a route id such as routes/abc123.","maxLength":200,"title":"Route Id","type":"string"},"external_id":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Only stops whose recipient external ID equals this.","title":"External Id"},"max_page_size":{"anyOf":[{"maximum":10,"minimum":1,"type":"integer"},{"type":"null"}],"default":10,"description":"How many results per page (1 to 10).","title":"Max Page Size"},"page_token":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Token from nextPageToken of the previous answer to get the next page.","title":"Page Token"}},"required":["route_id"],"title":"list_route_stopsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_drivers":{"post":{"operationId":"list_drivers","summary":"List drivers of the team with display name, active flag and depots. Contact details are not returned. Use for \"Which dri","description":"List drivers of the team with display name, active flag and depots. Contact details are not returned. Use for \"Which drivers are active\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"active":{"anyOf":[{"enum":["true","false"],"type":"string"},{"type":"null"}],"default":null,"description":"true for active drivers only, false for inactive ones.","title":"Active"},"max_page_size":{"anyOf":[{"maximum":50,"minimum":1,"type":"integer"},{"type":"null"}],"default":50,"description":"How many results per page (1 to 50).","title":"Max Page Size"},"page_token":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Token from nextPageToken of the previous answer to get the next page.","title":"Page Token"}},"title":"list_driversArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_depots":{"post":{"operationId":"list_depots","summary":"List the team's depots (start and end points) with their names. Use for \"What depots does my team have\".","description":"List the team's depots (start and end points) with their names. Use for \"What depots does my team have\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"max_page_size":{"anyOf":[{"maximum":20,"minimum":1,"type":"integer"},{"type":"null"}],"default":20,"description":"How many results per page (1 to 20).","title":"Max Page Size"},"page_token":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Token from nextPageToken of the previous answer to get the next page.","title":"Page Token"}},"title":"list_depotsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_unassigned_stops":{"post":{"operationId":"list_unassigned_stops","summary":"List stops that are not yet in a plan with depot, address, activity, package count and recipient external ID. Use for \"W","description":"List stops that are not yet in a plan with depot, address, activity, package count and recipient external ID. Use for \"Which stops are still waiting to be assigned to a plan\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"external_id":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Only stops whose recipient external ID equals this.","title":"External Id"},"max_page_size":{"anyOf":[{"maximum":20,"minimum":1,"type":"integer"},{"type":"null"}],"default":20,"description":"How many results per page (1 to 20).","title":"Max Page Size"},"page_token":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Token from nextPageToken of the previous answer to get the next page.","title":"Page Token"}},"title":"list_unassigned_stopsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/search_stops":{"post":{"operationId":"search_stops","summary":"Full-text search across all stops including unassigned ones, with an optional filter expression such as address.countryC","description":"Full-text search across all stops including unassigned ones, with an optional filter expression such as address.countryCode = \"DE\". Newly created stops can take a while to appear. Use for \"Find stops mentioning Springfield\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"keyword":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Words to match (fuzzy) against the text fields of stops.","title":"Keyword"},"filter":{"anyOf":[{"maxLength":500,"type":"string"},{"type":"null"}],"default":null,"description":"Filter expression, for example address.countryCode = \"DE\" and activity = \"pickup\".","title":"Filter"},"sort_order":{"anyOf":[{"enum":["asc","desc"],"type":"string"},{"type":"null"}],"default":"asc","description":"Sort direction: asc or desc.","title":"Sort Order"},"max_page_size":{"anyOf":[{"maximum":20,"minimum":1,"type":"integer"},{"type":"null"}],"default":20,"description":"How many results per page (default 20).","title":"Max Page Size"},"page_token":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Token from nextPageToken of the previous answer to get the next page.","title":"Page Token"}},"title":"search_stopsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_custom_stop_properties":{"post":{"operationId":"list_custom_stop_properties","summary":"List the custom stop properties defined by the team (ID, name, whether drivers and recipients can see them). Use for \"Wh","description":"List the custom stop properties defined by the team (ID, name, whether drivers and recipients can see them). Use for \"What custom stop fields does my team use\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{},"title":"list_custom_stop_propertiesArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}}}}