---
id: sdks.python
title: Python SDK Quickstart
summary: Install from source, submit a captured Fieldloop batch and inspect its processing receipt.
kind: quickstart
product_area: developer_tools
status: stable
updated: 2026-10-31
canonical: /docs/sdks/python
---

# Python SDK Quickstart

## Prerequisites and installation

Use Python 3.10+ and a source checkout of `teammately-python`. In your application's virtual environment:

```sh
python -m pip install /path/to/teammately-python
```

The distribution and import are both `teammately`. Configure `TEAMMATELY_API_KEY` through your host's secret mechanism, plus the existing organization, Project and source identifiers used below.

## Submit and inspect a batch

### Example: Capture one application record

```python
import os
from teammately import Batch, Client, FieldloopScope

client = Client(api_key=os.environ["TEAMMATELY_API_KEY"])
scope = FieldloopScope(
    organization=os.environ["TEAMMATELY_ORGANIZATION"],
    project=os.environ["TEAMMATELY_PROJECT"],
    source=os.environ["TEAMMATELY_FIELDLOOP_SOURCE"],
)
logs = [{
    "source_event_id": "support-ticket-1042:reply",
    "occurred_at": "2026-10-31T09:30:00Z",
    "input": {"question": "Has my bicycle shipped?"},
    "output": {"reply": "Your bicycle is being packed."},
}]
batch = Batch.prepare(logs, idempotency_key="support-ticket-1042:batch-1")
receipt = client.fieldloop.submit_batch(scope, batch)
processed = client.fieldloop.wait_receipt(scope, receipt.batch_id)
print(processed.accepted_count, processed.duplicate_count,
      processed.conflict_count, processed.rejected_count)
```

Replace this fictional record with selected, redacted application content. Your application owns event and batch keys; keep the key stable for the same logical batch. Teammately supplies destination and receipt IDs.

## Continuous ingestion

Create `client.fieldloop.ingestor(scope)`, call `add(log)`, then `close()` at shutdown. A context manager also closes it. `add` acknowledges memory. Optional capacities and deadlines are chosen by the caller; defaults do not impose a capacity or operation deadline.

Callbacks can run on a background thread: keep them thread-safe, return promptly and do not close the ingestor from them. This is a synchronous client. Async applications can use `asyncio.to_thread` for blocking calls. See [Delivery and Recovery](/docs/sdks/delivery-and-recovery).

## Success and recovery

Inspect row counts even when the batch is `processed`. A `ReceiptError` exposes its terminal processing receipt as `error.receipt`. Retain source records until admission is known; retry uncertain submission with the original bytes and key.

## Related reference pages

{% related-card-grid %}
- [SDK delivery and recovery](/docs/sdks/delivery-and-recovery)
- [Fieldloop API](/docs/public-api/fieldloop)
- [Fieldloop troubleshooting](/docs/troubleshooting/fieldloop)
{% /related-card-grid %}
