Connect Jobber to AI Agents: Automate Client and Request Workflows
Learn how to connect Jobber to AI agents using Truto's tools endpoint to automate client intake, work requests, and dispatching workflows.
You want to connect Jobber to an AI agent so your internal systems can independently triage work requests, generate client profiles, manage jobs, and dispatch field service resources based on historical context. Here is exactly how to do it using Truto's /tools endpoint and SDK, bypassing the need to hand-code complex REST and GraphQL API wrappers.
Giving a Large Language Model (LLM) read and write access to your Jobber instance is an engineering headache. You either spend weeks building, hosting, and maintaining a custom connector that navigates Jobber's specific pagination rules and mixed API paradigms, or you use a managed infrastructure layer that handles the boilerplate for you. If your team relies heavily on conversational interfaces, check out our guide on connecting Jobber to ChatGPT, or if you are building on Anthropic's models, read our guide on connecting Jobber to Claude. For developers building custom autonomous workflows, you need a programmatic way to fetch these tools and bind them to your agent framework.
This guide breaks down exactly how to fetch AI-ready tools for Jobber, bind them natively to an LLM using LangChain (or any framework like LangGraph, CrewAI, or Vercel AI SDK), and execute complex field service operations. For a deeper look at the architecture behind this approach, refer to our research on architecting AI agents and the SaaS integration bottleneck.
Why a Unified Tool Layer Matters for Agent Safety
Before writing a line of integration code, you must decide what layer your agent talks to. This choice determines how safe, predictable, and resilient your production system will be.
Direct API tools - writing one bespoke function per raw Jobber endpoint - look convenient in a weekend prototype. However, this approach pushes vendor-specific API quirks directly into the LLM's context window. The model is forced to remember that Jobber requires specific GraphQL mutations to update a client's email address, that isLead is a strictly managed boolean that cannot be updated directly via REST, and that deleting a client will fail if they have open jobs. Every one of those quirks is a hallucination waiting to happen.
Abstracting Jobber behind a standardized, schema-driven tool layer gives you concrete safety wins:
- Smaller attack surface for hallucination. The LLM only ever chooses from a stable, well-defined set of function names with explicit parameter boundaries.
- Deterministic input validation. Every tool provided by Truto has a strict JSON schema. Invalid arguments are rejected at the edge before they hit the Jobber API, so a broken tool call fails fast instead of creating malformed records.
- Centralized authentication. Your agent never sees or manages Jobber OAuth tokens. The LLM simply says "Create a request for this client ID," and the infrastructure handles the bearer tokens, refresh cycles, and tenant isolation.
The Engineering Reality of Custom Jobber Connectors
Building AI agents is easy. Connecting them to external SaaS APIs safely is hard. If you decide to build a custom Jobber connector yourself, you own the entire API lifecycle. Jobber's API introduces several highly specific integration challenges that break standard LLM assumptions.
The REST vs. GraphQL Schism
Jobber provides both a REST API and a GraphQL API, and they are not completely symmetric. For example, you can create a basic client record using a simple REST POST, but that endpoint only accepts scalar fields (like names). If your agent needs to add nested objects - such as phone numbers, billing addresses, or custom fields - the REST endpoint is insufficient. You have to use the GraphQL API's clientCreate mutation.
If you expose raw Jobber endpoints to an LLM, the model has to reason about when to use a REST path and when to construct a nested GraphQL mutation string. LLMs are notoriously bad at writing perfect GraphQL mutations on the fly. Truto solves this by providing clean, targeted REST proxy methods for simple scalar tasks, while providing a dedicated GraphQL tool as a controlled escape hatch for complex mutations.
Business Logic Guardrails
The Jobber API enforces strict workflow rules that an LLM will not intuitively know. For example, you cannot archive a client if they have active jobs or open work requests. If an LLM attempts this, Jobber throws a specific validation error. Furthermore, fields like requestStatus on a Work Request are driven entirely by Jobber's internal state machine; you cannot simply PATCH a request status to "completed." An agent must operate within these workflow guardrails, which means your tool descriptions must be highly explicit about what is and isn't allowed.
The Factual Reality of Rate Limits
AI agents in autonomous loops can easily execute 20 or 30 API calls in a few seconds while retrieving historical job data or searching for clients. Jobber heavily rate-limits these requests to protect their infrastructure, returning an HTTP 429 Too Many Requests status code.
Here is a critical architectural fact: Truto does not retry, throttle, or apply backoff on rate limit errors. When the upstream Jobber API returns an HTTP 429, Truto passes that error directly back to the caller.
What Truto does do is normalize the chaotic, vendor-specific rate limit headers into the standardized IETF specification. Regardless of how Jobber formats its headers, Truto returns ratelimit-limit, ratelimit-remaining, and ratelimit-reset.
As the developer, you are strictly responsible for catching the 429 response in your agent's execution loop, reading the ratelimit-reset header, and forcing the agent to sleep before retrying the tool call. Do not assume your infrastructure will magically absorb rate limits.
sequenceDiagram
participant Agent as "Agent Execution Loop"
participant Truto as "Truto Tool Proxy"
participant Jobber as "Jobber API"
Agent->>Truto: call list_all_jobber_clients
Truto->>Jobber: GET /clients
Jobber-->>Truto: HTTP 429 (X-Rate-Limit-Reset: 171500)
Truto-->>Agent: HTTP 429<br>ratelimit-reset: 45
Note over Agent: Agent must implement sleep(45s)<br>before retrying
Agent->>Truto: retry list_all_jobber_clients
Truto->>Jobber: GET /clients
Jobber-->>Truto: HTTP 200 OK
Truto-->>Agent: Unified JSON ResponseJobber AI Agent Tools You Can Use Instantly
Truto provides a comprehensive set of pre-configured tools for Jobber that map to its core resources. These tools handle the authentication routing and schema validation automatically. Here are the highest-leverage hero tools for field service workflows.
list_all_jobber_clients
This tool allows the agent to search and retrieve a list of clients in the Jobber account. It returns vital rollups, including totalCount for jobs, requests, quotes, and invoices. You can pass a filter object, such as {"isLead": true}, to narrow the results.
"Find all clients in Jobber who are marked as leads, and tell me which ones have zero total jobs booked."
create_a_jobber_request
Work requests are the lifeblood of Jobber. This tool allows the agent to create a new incoming work enquiry against an existing client ID. The request will automatically start with a requestStatus of "new".
"Create a new work request for client ID 98124. The title should be 'Emergency Leak Repair' and assign it to our default salesperson."
list_all_jobber_jobs
Once work is approved, it becomes a Job. This tool retrieves booked work, returning the job number, status, type, and scheduling timestamps. Agents use this to check schedule availability or verify if a customer's work has been completed.
"Pull the list of all jobs for the past week and filter for any that are not yet marked as completed."
jobber_requests_count
Retrieving hundreds of records just to count them burns through token context and API limits. This tool returns a simple totalCount of requests matching a specific filter, allowing agents to build quick diagnostic dashboards.
"Check the Jobber queue and tell me how many work requests currently have a status of 'new'."
create_a_jobber_graphql
This is the ultimate escape hatch. Because Jobber's REST API only accepts scalar fields for creation, your agent will need this tool to set complex nested data like emails, phone numbers, or custom status tags. It accepts a raw GraphQL query and variables payload.
"Use the GraphQL tool to execute a clientCreate mutation for 'Acme Corp', and ensure you attach the email address 'billing@acme.com' in the nested input array."
update_a_jobber_client_by_id
Used for simple, day-to-day data hygiene. This tool allows the agent to update a client's basic string details (like names or basic notes). It actively rejects attempts to update read-only fields like isLead.
"Update the client profile for ID 4451. Change their lead source to 'Inbound Marketing'."
For the complete schema definitions and the full inventory of available Jobber proxy methods, review the Jobber integration page.
Workflows in Action
Individual tools are useful, but chaining them together creates autonomous revenue and operations pipelines. Here are realistic examples of how an AI agent uses these tools in sequence to solve field service problems.
Scenario 1: Automated Lead Qualification & Intake
Persona: Sales Development Representative / Inbound Triage
"We just got an email from Jane Smith at Highland Properties asking for a roof inspection. Check if she is already in Jobber. If not, create a new lead profile for her, add her email (jane@highland.com), and lodge a new work request for the inspection."
Agent Execution Steps:
- The agent calls
list_all_jobber_clientswith a search filter for "Jane Smith" to prevent duplicate entries. - Finding no match, it calls
create_a_jobber_clientto generate the base profile (which Jobber defaults toisLead: true). - To add the nested email address, the agent calls
create_a_jobber_graphqlusing the returned client ID, executing a targeted mutation to append the contact details. - Finally, the agent calls
create_a_jobber_requestusing the client ID to log the incoming work enquiry.
Outcome: The user receives confirmation that the lead is logged, the contact data is enriched, and the dispatcher has a new request waiting in their queue - entirely hands-free.
Scenario 2: Dispatcher Capacity Auditing
Persona: Operations Manager / Dispatcher
"Give me a summary of our unassigned backlog. How many new requests are waiting in the system, and can you list the titles of the three oldest ones?"
Agent Execution Steps:
- The agent calls
jobber_requests_countwith the filter{"status": "new"}to get an immediate, low-latency integer of the backlog. - The agent then calls
list_all_jobber_requests, sorting bycreatedAtascending, and limiting the output to retrieve the context of the oldest items.
Outcome: The operations manager gets a precise numerical summary (e.g., "You have 14 new requests") along with actionable context on the most urgent pending jobs, without logging into the Jobber UI.
Building Multi-Step Workflows
To move this out of the conceptual phase and into production, you need an agent loop that binds these tools to an LLM and explicitly handles failures like rate limits.
Using the @trutohq/langchainjs-toolset (or a similar approach for Vercel AI SDK), you can dynamically fetch the Jobber tools for a specific authenticated tenant and inject them into your chosen model. Because Truto normalizes the rate limit headers, you can build a clean wrapper to catch HTTP 429s, respect the ratelimit-reset header, and retry the tool call.
Here is how you architect the agent loop in TypeScript:
import { ChatOpenAI } from "@langchain/openai";
import { AgentExecutor, createToolCallingAgent } from "langchain/agents";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { TrutoToolManager } from "@trutohq/langchainjs-toolset";
// 1. Initialize the LLM
const llm = new ChatOpenAI({
modelName: "gpt-4o",
temperature: 0,
});
// 2. Fetch the schema-driven tools for a specific Jobber account
// The integrated_account_id represents the specific Jobber tenant
const toolManager = new TrutoToolManager({
trutoToken: process.env.TRUTO_API_KEY,
integratedAccountId: "jobber_acc_12345abcde"
});
async function runJobberAgent(userPrompt: string) {
try {
// Fetch tools dynamically via Truto's /tools endpoint
const tools = await toolManager.getTools();
// 3. Define the Agent Prompt
const prompt = ChatPromptTemplate.fromMessages([
["system", "You are a field service operations assistant. You manage Jobber data. Always search for existing records before creating new ones."],
["placeholder", "{chat_history}"],
["human", "{input}"],
["placeholder", "{agent_scratchpad}"],
]);
// 4. Create the [Tool Calling Agent](/what-is-llm-function-calling-for-integrations-2026-guide/)
const agent = createToolCallingAgent({
llm,
tools,
prompt,
});
const agentExecutor = new AgentExecutor({
agent,
tools,
// Note: Truto passes 429s back to the agent.
// In a production LangChain setup, you should use handleParsingErrors
// or a custom tool wrapper to read the 'ratelimit-reset' header and sleep.
handleParsingErrors: true,
maxIterations: 10,
});
// 5. Execute the Workflow
console.log(`Executing request: ${userPrompt}`);
const result = await agentExecutor.invoke({
input: userPrompt,
});
console.log("Agent Response:", result.output);
} catch (error) {
// 6. Explicitly handle rate limits if they bubble up
if (error.response?.status === 429) {
const resetTime = error.response.headers.get('ratelimit-reset');
console.error(`Rate limited by Jobber. Must sleep for ${resetTime} seconds.`);
// Implement your application-level backoff here
} else {
console.error("Agent execution failed:", error);
}
}
}
// Execute the intake scenario
runJobberAgent(
"Find the client 'Highland Properties'. If they exist, check if they have any active jobs. If not, create a new work request for a roof inspection."
);In this architecture, the integration layer is entirely declarative. If Jobber adds a new required field to their REST API tomorrow, or if you need to switch from a LangChain orchestrator to LangGraph or CrewAI, your tool integration code does not change. The /tools endpoint dynamically provides the updated schema, and the agent adapts immediately.
Strategic Wrap-Up
Building AI agents that read and write against Jobber requires strict operational boundaries. Hand-rolling API connectors forces your engineering team to manage Jobber's idiosyncrasies - parsing mixed REST and GraphQL responses, managing complex OAuth lifecycles, and keeping LLMs from hallucinating invalid payloads.
By leveraging a unified tool layer, you abstract away the API mechanics. The agent interacts with clean, deterministic functions, and your infrastructure cleanly bubbles up standard HTTP errors - like rate limits and ratelimit-reset headers - so your code can handle backoffs predictably.
Stop writing custom wrappers and start building autonomous workflows that actually drive field service efficiency.
FAQ
- Does Truto automatically handle Jobber API rate limits for my agent?
- No. Truto does not retry, throttle, or apply backoff on rate limit errors. When Jobber returns an HTTP 429, Truto passes that error to your agent, while normalizing the upstream rate limit info into standardized headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset). Your agent framework is responsible for implementing retry and backoff logic.
- Can I use Truto's tools with any LLM framework?
- Yes. Truto's tools endpoint returns standardized JSON schemas for every proxy API, which can be bound natively to LangChain, LangGraph, CrewAI, Vercel AI SDK, or any framework that supports tool calling.
- How do I handle complex Jobber fields that aren't supported in the standard REST endpoints?
- Truto provides a dedicated create_a_jobber_graphql tool, which acts as an escape hatch. You can pass arbitrary GraphQL queries and mutations to manage nested objects, custom fields, and complex status tags that the basic REST tools cannot express.