Skip to main content

Conecto for Python

The official Python SDK for Conecto — build chat bots, plugins and integrations on top of a live customer-messaging platform.

pip install conecto
from conecto import Conecto

client = Conecto()  # reads CONECTO_CLIENT_ID / CONECTO_SECRET

for convo in client.conversations.list(status="open"):
    print(convo.id, convo.preview)

Credentials come from the dashboard: Settings → Developers → new credential. The secret is shown once.


What you can build

1. Automate the workspace

Everything the platform does, driven from your code — conversations, contacts, tickets, help articles, widget configuration, proactive messages.

client.contacts.upsert("maya@acme.io", name="Maya", custom_fields={"plan": "pro"})

client.tickets.create(email="maya@acme.io", message="Card declined", priority="high")

client.visitors.message(
    widget_id=7, session=session_id,
    body="Your order shipped — want live tracking?",
    buttons=["Track my order"],
)

2. Build a bot

A bot is a webhook and a reply. Signature verification, delivery deduplication, event routing and "don't answer your own messages" are handled; you write the part that is yours.

from conecto import Conecto, Bot, blocks

client = Conecto()
bot = Bot(client, secret=WEBHOOK_SECRET)

@bot.on_message
def handle(ctx):
    if "refund" in ctx.text.lower():
        ctx.reply(
            "I can start a refund. Which order?",
            buttons=["#1284", "Something else"],
        )
    elif "how do i reset" in ctx.text.lower():
        ctx.reply("Here's how:", blocks=[
            blocks.image("https://cdn.you.com/reset.gif", alt="Reset flow"),
            blocks.buttons([
                blocks.reply_button("That worked"),
                blocks.link_button("Full guide", "https://docs.you.com/reset"),
            ]),
        ])
    else:
        ctx.note("Bot didn't recognise this — handing over.")
        ctx.handoff_to_team(reason="Bot could not classify the request")
        return

# Flask
app.add_url_rule("/conecto", view_func=bot.flask_view(), methods=["POST"])

Adapters ship for Flask, FastAPI, Django and bare WSGI.

For an asynchronous queue instead of live chat, create a ticket that remains linked to the transcript. The visitor's known name and email are reused automatically:

result = ctx.handoff_to_ticket(
    "Refund needs a billing specialist",
    priority="high",
)
return  # the custom agent must stop after either kind of handoff

3. Build a plugin

Declare what your systems can do, and the AI agent calls them mid-conversation. Your store, your billing, your CRM — whatever software they run on.

from conecto import Conecto, Plugin, parameter

plugin = Plugin("acme-store", base_url="https://api.acme.com/conecto")

@plugin.action(
    "catalog.search_products",                       # a reserved name: results become
    description="Search the Acme catalog by keyword.",  # product cards automatically
    parameters=[parameter("query", type="string", required=True)],
)
def search(req):
    hits = catalog.search(req.arguments["query"], limit=4)
    if not hits:
        return req.not_found()
    return req.ok(products=[
        {"title": p.name, "url": p.url, "image": p.image,
         "price_from": f"{p.price:.2f}", "currency": "USD", "available": p.stock > 0}
        for p in hits
    ])

@plugin.action(
    "orders.get_status",
    risk="verified_read",                            # refused until identity is proven
    description="Status of one of the visitor's own orders.",
    parameters=[parameter("order_number", required=True)],
)
def order_status(req):
    order = orders.find(req.arguments["order_number"], email=req.verified_email)
    return req.ok(**order) if order else req.not_found()

app.add_url_rule("/conecto/<path:action>", view_func=plugin.flask_view(),
                 methods=["POST"])

plugin.deploy(Conecto())   # idempotent — run it on every release

That is a complete storefront integration. The product cards, the Home showcase and the identity checks come with it.


Rich content

Any message can carry images, GIFs, video, audio, files, embeds, card carousels, label/value lists and buttons.

from conecto import blocks

convo.reply("Here's your order:", blocks=[
    blocks.list_block([
        blocks.row("Placed", "12 July 2026"),
        blocks.row("Status", "Shipped"),
        blocks.row("Carrier", "DHL", subtitle="Tracking 4Z8871",
                   url="https://track.dhl.com/4Z8871"),
    ], title="Order #1042"),
    blocks.cards([
        blocks.card("Trail Runner 2", price="89.00 USD", badge="Back in stock",
                    image="https://cdn.you.com/tr2.jpg",
                    url="https://shop.you.com/p/tr2",
                    buttons=[blocks.link_button("Buy", "https://shop.you.com/cart")]),
    ]),
])

No public URL for that GIF? Upload it:

media = client.media.upload("celebrate.gif")
convo.reply("All set!", blocks=[blocks.image(media)])

Every builder validates locally, so a typo raises BlockError from your line instead of coming back as an HTTP 400.


Identity

Actions that touch one person's data will not run until we have proven who they are — by an emailed code, or because your site vouched for a logged-in user:

# your backend, right after your own auth check
client.visitors.identify(
    widget_id=7, session=conecto_session,
    email=user.email, name=user.name,
    verified=True, verify_hours=24,
    data={"plan": user.plan},
)

# on logout
client.visitors.unverify(widget_id=7, session=conecto_session)

Inside a plugin, req.verified_email is the address we proved. An email in req.arguments is whatever the model parsed out of a chat — never authorization.


Things that will save you an afternoon

Verify webhooks against the raw body. Re-serializing JSON changes the bytes and the signature stops matching. This is the most common first-integration bug, and the SDK raises a message saying so if you pass a parsed dict.

event = webhooks.parse(request.get_data(), request.headers, secret=SECRET)

Deliveries are at-least-once. Dedupe on event.id, and pass it as your idempotency key when replying — Bot does both for you.

Pagination iterates itself.

page = client.contacts.list(query="acme")
page.items      # this page
for c in page:  # every page, fetched lazily
    ...
page.all()      # everything, in one list

Errors are typed.

from conecto import ConversationClosed, RateLimited

try:
    convo.reply("Refunded.")
except ConversationClosed:
    convo.reopen()
    convo.reply("Refunded.")

Retries for timeouts, 429s and 5xx are automatic and honour Retry-After. Writes are retried safely because every write carries an idempotency key.


Reference

client.conversations list, read, reply, typing, team/ticket handoff, assign, close
client.contacts upsert by email, search, update, delete
client.visitors identify + vouch, unverify, proactive messages
client.tickets create, update, reply, categories
client.articles search and publish help-center content
client.integrations register, install, run and deploy plugins
client.widgets read and update widget configuration
client.media upload files for blocks
client.webhooks subscribe endpoints to events
client.members teammates, for assignment
client.meta me(), schema(), stats()

client.meta.schema() returns the whole API described as JSON — endpoints, events, block types, reserved actions and every limit — served by the same code that enforces them.

Requirements: Python 3.9+ and requests.

Full documentation: https://conecto.chat/developers/python — every method, worked examples, and an Ask Claude / ChatGPT / Grok button on each section.

REST API reference: https://conecto.chat/developers · Issues: https://github.com/Nancy-Consulting/conecto-sdk/issues

MIT licensed.

Metadata

Release files for conecto 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for conecto 0.2.0
File Size Uploaded
conecto-0.2.0.tar.gz 66.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for conecto 0.2.0
File Interpreter ABI Platform
conecto-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 126.3 kB

Release files / conecto-0.2.0.tar.gz

Download URL conecto-0.2.0.tar.gz
Size 66.6 kB
Tags Source
SHA-256 checksum
How to use checksums
cbef1c25ae155499611959ac2334b504399694ead16384cc1d49f44717efda9f
BLAKE2b-256 checksum
How to use checksums
63462bd23f4beb02ee4657ee26bb74afa76560aebc9038e627b244ed9703b34c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.3

Release files / conecto-0.2.0-py3-none-any.whl

Download URL conecto-0.2.0-py3-none-any.whl
Size 59.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4d197936675cfc9cee59b5207c446e8abb37e3117a1277b85bf5a30623258279
BLAKE2b-256 checksum
How to use checksums
f780dcc83062697de7586585fe4af8aee8cee2f41069eb745a8187a3a71faa28
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.3

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page