gumloop package lets you call Gumloop from Python. The same agents you build in the app can be started, streamed, and managed from a script, a backend service, or a CI job. The package also installs the gumloop CLI, and every CLI command runs through the SDK.
For raw HTTP, see the API reference.
Overview
The package ships two clients:Core concepts
Installation
Authentication
Every client needs a credential. Pick one:
Your API key is in the Gumloop API key row of your Profile settings page, and your user ID is in the User ID row just above it. See Find your Gumloop API key and Personal vs team keys.
Team API keys
Team keys are scoped to one team. Pass the team’s ID and the user ID of the member you’re acting as. Every request is checked against that team and only reaches resources the team owns.Environment variables
Any argument you leave out is read from the environment:GUMLOOP_API_KEY is read by the CLI, not by the SDK. In Python, use GUMLOOP_ACCESS_TOKEN or pass api_key=.AuthenticationError.
OAuth
client.oauth has the OAuth 2.0 + PKCE helpers for apps that other Gumloop users sign in to. The OAuth flow itself is covered in OAuth.
gumloop and userinfo. Pass scopes= to register_client and build_authorization_url to change them.
OAuth access to the Gumloop API requires the Pro plan or above. A token for an account below Pro is refused with
403 and the error tier_required_pro. API keys don’t have this plan check.Quick start
List your agents, start a session with one, and stream the reply:Async usage
AsyncGumloop takes the same arguments and has the same resources as Gumloop. Await each call, and use async for on streams.
Client options
Both clients hold an HTTP connection pool. Use them as context managers (
with Gumloop(...) as client: or async with AsyncGumloop(...) as client:), or call client.close() / await client.aclose() when you’re done.
Run an agent
A session is one conversation with an agent. You can wait for the agent’s reply, or stream it as it’s generated.Start a session
client.sessions.create(agent_id, input=...) starts a session and returns a SessionResponse. The agent may still be working when it returns, so poll retrieve until the session’s state is completed or failed.
A
Session carries id, agent_id, name, type, state, messages, created_at, usage (credit_cost, input_tokens, output_tokens, and more), and incognito. SessionResponse.queue_position is set when the session is waiting in a queue.
Stream a session
client.sessions.stream(agent_id, input=...) starts a session and yields StreamEvent objects as the agent works. It’s the same as create(..., stream=True).
StreamEvent has:
If your connection drops, pick the stream back up from the last cursor you saw:
Send a follow-up
send takes stream=True too. Both raise ValueError if you don’t pass input.
List, rename, and cancel
list also filters by search, type (for example api, chat, or slack), creator_user_id, trigger_id, and sort_order.
Incognito sessions
Passincognito=True to create or stream for an incognito session. To make every session on an agent incognito, call client.agents.set_incognito(agent_id, True). That needs the Incognito agents role permission, and fails with organization_permission_required without it.
Chat completions
client.chat.completions.create(...) is an OpenAI-compatible chat surface that routes to every model Gumloop supports (Anthropic, OpenAI, Google Gemini, OpenRouter routes). The streaming variant returns an iterator of ChatStreamChunk, and the unary variant returns a ChatResult.
model must be a concrete model. gumloop-chew, the Auto router, picks a model instead of being one. Use client.models.route(...) (or POST /models/route) to get the model it would choose, then pass that here. Requires a current gumloop package that includes the models resource.Streaming
Structured output
Passresponse_format={"type": "json_schema", "json_schema": {...}} to constrain the response to a JSON Schema. The SDK accepts the same shape the OpenAI API documents.
Image generation
Request an image-generation model such asgpt-image-2.5-flare or gemini-*-image-preview with modalities=["image", "text"]. The response carries image attachments on choices[0].message.images as data URLs. Streaming variants emit partial frames natively for OpenAI gpt-image models.
Tool calling
Pass OpenAI-shape tool definitions. The SDK forwards them unchanged so any LLM that supports function calling can invoke them.Bring your own provider key
When the calling user has configured their own provider API key (OpenAI, Anthropic, etc.) in Gumloop, billing follows that account’s pricing policy. Usage pricing can waive inference for BYOK, and some legacy organizations use a partial discount. See Credits. You don’t need to change any SDK code.Pick a model with Auto
client.models.route(...) asks Auto (gumloop-chew) which model should handle a task. It only returns the decision: nothing runs.
models to route across the full Auto catalog. client.models.list() returns the models you can use, grouped as they are in the app.
MCP tools
client.mcp.execute(...) returns an McpExecuteResponse with one result per tool call. The SDK reports MCP execution failures, such as target server authentication errors or upstream connection failures, on each result instead of raising APIStatusError. Gumloop request errors, such as missing credentials, invalid request bodies, or endpoint permission failures, can still raise APIStatusError.
decoded_content is a Python SDK convenience property. Raw REST responses include the underlying content array.
Servers, tools, and accounts
list_accounts returns each one’s id, label, and is_default. Pass account= to pick one. Without it, the default account is used. client.mcp.execute_many([...]) runs several calls in one request and returns one result per call, in order. list_resources, get_resource, list_prompts, and get_prompt read a server’s MCP resources and prompts.
Agent configuration
Everything the agent panel can set is available throughclient.agents. create takes the whole configuration in one call. After that, settings change through update, and each collection has its own attach/detach pair so one item changes without re-sending the rest.
retrieve returns the whole agent: tools, metadata, abilities, skill_ids, knowledge_sources, triggers and version. Pass that version back on update and the call fails with agent_version_conflict if someone else saved the agent in between. Leave it out and the last write wins.
create_trigger and from get_trigger_webhook_url, never in list_triggers or retrieve. delete removes a custom agent. You can read and chat with gumball and analytics, but not configure them.
Agent versions
Every agent keeps an immutable history of its configuration.client.agents.list_versions(...) pages through those snapshots newest-first, and client.agents.get_version(...) returns one version’s full configuration plus the structured diff against the version before it.
Evaluations
client.agents.list_evaluations(...) pages through an agent’s graded chats newest-first, client.agents.get_evaluation_metrics(...) returns grade and tag counts over a window, and client.agents.run_evaluations(...) queues evaluations for finished sessions. client.agents.get_evaluation_options() lists the criterion types, priorities, and limits the config accepts.
dry_run=True to see the cost and the sessions it would skip (unfinished, or already queued) without queuing anything. To list results from an organization evaluation enforced on the agent, call list_evaluations(agent_id, organization_evaluation_id=...).
Organization evaluations
client.evaluations manages rubrics an organization admin defines once and applies to teams, people, or individual agents (Enterprise plan, Manage evaluations permission). A new evaluation starts disabled: set its targets, then enable it. Run it over past sessions with run(...). Grading is asynchronous, so poll each returned result id.
client.evaluations.options() returns the size limits and the allowed values for every enum field: grades, statuses, target types, session types, and criterion priorities.
Company Brain
client.brain.search(...) runs a hybrid (semantic + keyword) search across the knowledge sources indexed in your Company Brain and returns ranked results scoped to what you can access. Brain is available on the Pro and Enterprise plans, and each search consumes credits.
document_id, source, title, content, url, score, updated_at, owner_name, owner_email, parent_title, and metadata. Omit source_type to search every source you can access. Valid values are notion, google_drive, slack, github, confluence, direct_file_uploads, and gumloop_artifacts.
Sources and files
Create file-upload sources and put files into them. The SDK can only createdirect_file_uploads sources. You set up connected sources in the app.
list_sources(scope=..., source_type=..., team_id=..., page_size=..., cursor=...) and get_source(id) read sources of every type. A source created with require_approval=True is a draft: get_estimate(id).estimate.estimated_credits shows the cost once estimate.status is paused_for_approval, and approve_source(id) starts indexing. Every file’s sha256 lets you diff a local folder against a source. The CLI’s gumloop brain sync does exactly that.
Skills
client.skills uploads, updates, downloads, and deletes skills. Files are passed as a {filename: content} mapping and must include a SKILL.md.
client.skills.list(...) filters by team_id, search_query, creator_user_id, related_server_id, and agent_id, and pages with page_size and cursor.
Artifacts
Artifacts are the files agents produce. List them per agent or per session, then download one through a signed URL.version_id= to download for an older version. client.artifacts.set_password(artifact_id, "...") protects an artifact’s share link with a password.
Sharing
Sessions, skills, and artifacts share the same access methods:get_access(id) and update_access(id, share=..., remove=..., link=...).
person (with email), team (with team_id), or organization. Link modes are none, anyone, and password. Leave out the link role to use the item’s default. The roles each item accepts are listed in Sharing roles.
Teams and organizations
Browser profiles
Agents that use the Browser ability keep their sign-ins in a browser profile.client.browser_profiles.list() lists the profiles you can use, and client.browser_profiles.import_cookies(profile_id, cookies=[...], url=...) adds cookies to one. Pass team_id= for a team profile. The CLI’s gumloop browser import-logins reads cookies from your local browser and calls this for you.
Errors
Every SDK error subclassesGumloopError:
APIStatusError has the details of the failed request:
Flows (legacy client)
project_id when creating the client if running automations in a workspace: