NewsOperate As is live. Send your first client one link
All news

Developers

October 22, 2026

Build with the Python library

A ten-minute walkthrough: list your clients, read a client's Google Sheet, type their services, and handle a client who needs to reconnect.

Shane Arcaro

Developers

Build with the Python library

On this page

Operate As works from AI agents over MCP, from n8n, and from plain HTTPS. When you're writing your own code, our libraries for Python, TypeScript and Go make it shorter: every service comes as a typed package, every error has a name, and your clients' tokens never touch your code.

This walkthrough uses the Python library. In about ten minutes you'll list your clients, read rows from a client's Google Sheet, and handle a client who needs to reconnect.

Before you start

You need an Operate As account with at least one client who has connected a service. Then create an API key on the dashboard's API & webhooks page. You can limit it to specific clients, services and actions, and it's shown only once, so keep it somewhere safe.

Store the key in an environment variable rather than in your code:

export OPERATE_AS_API_KEY="oa_..."

Install

The library needs Python 3.9 or newer and has no dependencies beyond the standard library. Each service has a typed package of its own, such as operate-as-sheets, with every action as a method. Install the library and the services you use:

pip install operate-as operate-as-sheets operate-as-slack

With uv, it's uv add operate-as operate-as-sheets operate-as-slack, and with Poetry, poetry add the same packages.

List your clients

Create one OperateAs with your key and reuse it everywhere. It's safe to share between threads.

import os

from operate_as import OperateAs

operate = OperateAs(os.environ["OPERATE_AS_API_KEY"])

for client in operate.clients.list():
    print(client.id, client.name, client.services)  # 6f1c2a7e-... Miller Dental ['sheets', 'slack']

You only see the clients your key can reach. To find the ones with a particular service connected, pass service.

Work in a client's accounts

Pick a client by their id, and hand them to each service's package:

from operate_as_sheets import Sheets
from operate_as_slack import Slack

client = operate.client("6f1c2a7e-...")  # Miller Dental, with sheets and slack connected

rows = Sheets(client).read_rows(spreadsheet_id="1BxiM...", range="A1:D20")
Slack(client).send_message(channel="#front-desk", text=f"{len(rows.data['values'])} bookings today")

Operate As attaches the client's access on our server, calls Google and Slack, and hands back each service's own status and response. Your code never sees a token.

Every input is typed and documented, so your editor completes it and Pyright or mypy catches a misspelled one.

Each client only has the services they've connected. Call one they haven't, like HubSpot for a client without it, and you get a ReconnectRequiredError that says so. Use a client from operate.clients.list() and it's a NotConnectedError straight away, before anything is sent, naming the services they do have.

Call any endpoint

When a ready-made action doesn't cover what you need, call the service's own API directly. Give the path as the service documents it, and we add the client's access:

deal = operate.request(
    "6f1c2a7e-...",
    "hubspot",
    "POST",
    "/crm/v3/objects/deals",
    body={"properties": {"dealname": "Spring campaign", "amount": "4200"}},
)
print(deal.status)

This needs only the library, so it works for every service, packaged or not.

Handle a client who needs to reconnect

Access can end when a client changes their password or removes it. Instead of failing quietly, the library raises ReconnectRequiredError, so you can tell your team or send the client their link. NotConnectedError is a kind of ReconnectRequiredError, so the same handler catches both:

import operate_as

try:
    Sheets(client).add_row(spreadsheet_id="1BxiM...", range="A1", values=["2026-10-22", "Emma Carter"])
except operate_as.ReconnectRequiredError as error:
    print(f"Miller Dental needs to reconnect: {error.detail}")
except operate_as.OperateAsError as error:
    print(error.status, error.detail)

Every error carries a status and a detail written to be shown to a person.

Give agents short-lived keys

If an AI agent is calling Operate As, keep your main key on your server and hand each run a short-lived key instead. It reaches no more than your key, can be narrowed further, and stops working when it expires:

short = operate.keys.create_short_lived(expires_in=900, services=["sheets"])

agent = OperateAs(short.secret)  # or use short.secret as the agent's MCP bearer token

What's next

  • Hear about changes as they happen. Add a webhook on the API & webhooks page, and check each delivery with Webhook.verify from the library.
  • Using another language? The TypeScript and Go libraries work the same way, with the same key.
  • Building with an AI agent? Point Claude, ChatGPT or Cursor at our MCP server, and it gets the same tools.

See every option on the developers page.

Get started

Send your next client one link

Add a client, select the services, copy the link. You'll get an email the moment their access is ready. Start free, no card required. Paid plans are one flat monthly price, and a busy month never takes your agents offline.