Skip to main content
The 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

Or with uv:
Requires Python 3.10 or later. The SDK works on Windows, macOS, and Linux. (The CLI that ships in the same package is macOS and Linux only.)

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=.
If no credential is found, the first request raises 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.
The default scopes are 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).
Each 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

Pass incognito=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

Pass response_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 as gpt-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.
Leave out 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

When you have more than one account connected to a server, 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 through client.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.
One 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.
A webhook trigger’s URL embeds its secret. It comes back once on 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.
Both calls require configuration access on the agent and only read data. Deploying or restoring a version has to happen in the app.

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.
Listing and metrics need read access on the agent and cover the chats you can see. Running evaluations needs edit access and consumes one credit per session. Pass 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.
Each result carries 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 create direct_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.
Pass 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=...).
Share entries are 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 subclasses GumloopError: APIStatusError has the details of the failed request:

Flows (legacy client)

Optionally add a project_id when creating the client if running automations in a workspace: