{"openapi":"3.1.0","info":{"title":"ServiceM8 (BYOK) API","version":"0.1.0","description":"ServiceM8 (BYOK) lets an AI assistant read your own ServiceM8 data through the ServiceM8 API with a key you supply (ServiceM8 API key). Read-only: 10 tools (list_jobs, list_clients, list_staff, list_job_activities, list_job_allocations, list_job_payments, list_job_materials, list_job_queues, list_categories, list_locations). The BYOK key travels with each request, is used for that one call only...\n\nEvery operation is read-only or compute-only. The same tools are available over MCP (streamable HTTP) at https://byok-servicem8.connectorbay.com/mcp.","contact":{"name":"Unify Dynamics LLC","email":"agent@connectorbay.com","url":"https://connectorbay.com/byok-servicem8/docs"},"termsOfService":"https://connectorbay.com/byok-servicem8/terms"},"servers":[{"url":"https://byok-servicem8.connectorbay.com"}],"externalDocs":{"url":"https://connectorbay.com/byok-servicem8/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_jobs":{"post":{"operationId":"list_jobs","summary":"List jobs (quotes, work orders, completed) with status, address, description, client, invoice total and dates. The API r","description":"List jobs (quotes, work orders, completed) with status, address, description, client, invoice total and dates. The API returns records in its own order; narrow with the filter. Use for \"Which ServiceM8 jobs are currently work orders\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"filter":{"anyOf":[{"maxLength":250,"type":"string"},{"type":"null"}],"default":null,"description":"Optional OData-style filter, for example \"status eq 'Work Order' and active eq 1\". Operators eq, ne, gt, lt joined by 'and' (max 10); text values in single quotes.","title":"Filter"},"cursor":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}],"default":null,"description":"Use -1 to start a paged read (up to 1000 records, of which the first 50 are shown); omit for the default read.","title":"Cursor"}},"title":"list_jobsArguments","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_clients":{"post":{"operationId":"list_clients","summary":"List clients (customer companies and individuals) with name, address, website and active flag. Use for \"Find the Service","description":"List clients (customer companies and individuals) with name, address, website and active flag. Use for \"Find the ServiceM8 client named Smith & Sons\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"filter":{"anyOf":[{"maxLength":250,"type":"string"},{"type":"null"}],"default":null,"description":"Optional OData-style filter, for example \"status eq 'Work Order' and active eq 1\". Operators eq, ne, gt, lt joined by 'and' (max 10); text values in single quotes.","title":"Filter"},"cursor":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}],"default":null,"description":"Use -1 to start a paged read (up to 1000 records, of which the first 50 are shown); omit for the default read.","title":"Cursor"}},"title":"list_clientsArguments","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_staff":{"post":{"operationId":"list_staff","summary":"List staff members with name, job title, schedule visibility and active flag (no contact details or live location). Use ","description":"List staff members with name, job title, schedule visibility and active flag (no contact details or live location). Use for \"Who is on the ServiceM8 field team\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"filter":{"anyOf":[{"maxLength":250,"type":"string"},{"type":"null"}],"default":null,"description":"Optional OData-style filter, for example \"status eq 'Work Order' and active eq 1\". Operators eq, ne, gt, lt joined by 'and' (max 10); text values in single quotes.","title":"Filter"},"cursor":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}],"default":null,"description":"Use -1 to start a paged read (up to 1000 records, of which the first 50 are shown); omit for the default read.","title":"Cursor"}},"title":"list_staffArguments","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_job_activities":{"post":{"operationId":"list_job_activities","summary":"List scheduled or recorded job activities (visits) with staff, start and end times and travel time. Use for \"What visits","description":"List scheduled or recorded job activities (visits) with staff, start and end times and travel time. Use for \"What visits are scheduled in ServiceM8 for job abc\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"filter":{"anyOf":[{"maxLength":250,"type":"string"},{"type":"null"}],"default":null,"description":"Optional OData-style filter, for example \"status eq 'Work Order' and active eq 1\". Operators eq, ne, gt, lt joined by 'and' (max 10); text values in single quotes.","title":"Filter"},"cursor":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}],"default":null,"description":"Use -1 to start a paged read (up to 1000 records, of which the first 50 are shown); omit for the default read.","title":"Cursor"}},"title":"list_job_activitiesArguments","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_job_allocations":{"post":{"operationId":"list_job_allocations","summary":"List which staff member or queue each job is allocated to, with allocation date and completion time. Use for \"Who is eac","description":"List which staff member or queue each job is allocated to, with allocation date and completion time. Use for \"Who is each ServiceM8 job allocated to\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"filter":{"anyOf":[{"maxLength":250,"type":"string"},{"type":"null"}],"default":null,"description":"Optional OData-style filter, for example \"status eq 'Work Order' and active eq 1\". Operators eq, ne, gt, lt joined by 'and' (max 10); text values in single quotes.","title":"Filter"},"cursor":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}],"default":null,"description":"Use -1 to start a paged read (up to 1000 records, of which the first 50 are shown); omit for the default read.","title":"Cursor"}},"title":"list_job_allocationsArguments","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_job_payments":{"post":{"operationId":"list_job_payments","summary":"List payments recorded against jobs with amount, method, time and whether it was a deposit. Use for \"What payments were ","description":"List payments recorded against jobs with amount, method, time and whether it was a deposit. Use for \"What payments were recorded in ServiceM8 recently\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"filter":{"anyOf":[{"maxLength":250,"type":"string"},{"type":"null"}],"default":null,"description":"Optional OData-style filter, for example \"status eq 'Work Order' and active eq 1\". Operators eq, ne, gt, lt joined by 'and' (max 10); text values in single quotes.","title":"Filter"},"cursor":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}],"default":null,"description":"Use -1 to start a paged read (up to 1000 records, of which the first 50 are shown); omit for the default read.","title":"Cursor"}},"title":"list_job_paymentsArguments","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_job_materials":{"post":{"operationId":"list_job_materials","summary":"List materials and line items added to jobs with name, quantity and price. Use for \"What materials were used on ServiceM","description":"List materials and line items added to jobs with name, quantity and price. Use for \"What materials were used on ServiceM8 job abc\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"filter":{"anyOf":[{"maxLength":250,"type":"string"},{"type":"null"}],"default":null,"description":"Optional OData-style filter, for example \"status eq 'Work Order' and active eq 1\". Operators eq, ne, gt, lt joined by 'and' (max 10); text values in single quotes.","title":"Filter"},"cursor":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}],"default":null,"description":"Use -1 to start a paged read (up to 1000 records, of which the first 50 are shown); omit for the default read.","title":"Cursor"}},"title":"list_job_materialsArguments","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_job_queues":{"post":{"operationId":"list_job_queues","summary":"List job queues (inboxes) with name, default timeframe and whether assignment is required. Use for \"What job queues exis","description":"List job queues (inboxes) with name, default timeframe and whether assignment is required. Use for \"What job queues exist in ServiceM8\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"filter":{"anyOf":[{"maxLength":250,"type":"string"},{"type":"null"}],"default":null,"description":"Optional OData-style filter, for example \"status eq 'Work Order' and active eq 1\". Operators eq, ne, gt, lt joined by 'and' (max 10); text values in single quotes.","title":"Filter"},"cursor":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}],"default":null,"description":"Use -1 to start a paged read (up to 1000 records, of which the first 50 are shown); omit for the default read.","title":"Cursor"}},"title":"list_job_queuesArguments","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_categories":{"post":{"operationId":"list_categories","summary":"List job categories with name and colour. Use for \"What job categories are set up in ServiceM8\".","description":"List job categories with name and colour. Use for \"What job categories are set up in ServiceM8\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"filter":{"anyOf":[{"maxLength":250,"type":"string"},{"type":"null"}],"default":null,"description":"Optional OData-style filter, for example \"status eq 'Work Order' and active eq 1\". Operators eq, ne, gt, lt joined by 'and' (max 10); text values in single quotes.","title":"Filter"},"cursor":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}],"default":null,"description":"Use -1 to start a paged read (up to 1000 records, of which the first 50 are shown); omit for the default read.","title":"Cursor"}},"title":"list_categoriesArguments","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_locations":{"post":{"operationId":"list_locations","summary":"List business locations (depots, warehouses) with name, address and coordinates. Use for \"Which locations does the Servi","description":"List business locations (depots, warehouses) with name, address and coordinates. Use for \"Which locations does the ServiceM8 account have\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"filter":{"anyOf":[{"maxLength":250,"type":"string"},{"type":"null"}],"default":null,"description":"Optional OData-style filter, for example \"status eq 'Work Order' and active eq 1\". Operators eq, ne, gt, lt joined by 'and' (max 10); text values in single quotes.","title":"Filter"},"cursor":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}],"default":null,"description":"Use -1 to start a paged read (up to 1000 records, of which the first 50 are shown); omit for the default read.","title":"Cursor"}},"title":"list_locationsArguments","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}}}}