enfinitos-sdk-brand (Python)
EnfinitOS Brand/Advertiser SDK — a lightweight async REST client that lets a brand (advertiser) query its own delivery proof, metering, and settlement records directly, without going through the operator's reporting plane. Read-only by design and scoped to campaigns the brand owns.
Python counterpart of @enfinitos/sdk-brand (TypeScript). Same shape, idiomatic Python: async-first via httpx.AsyncClient, pydantic v2 models.
Who should use this
You are a brand (advertiser) and:
- you want to reconcile EnfinitOS invoices against your own impression logs or auditor analysis;
- you need to file disputes backed by signed counter-evidence the operator is contractually bound to respond to;
- your data pipeline is async (FastAPI / Prefect / Airflow with async tasks / Temporal).
If you are an operator, you want the operator-web SDK instead. If you are an auditor verifying signatures, you want enfinitos-sdk-auditor for the cryptographic primitives.
Authentication
Authorization: Bearer brk_…
X-Enfinitos-Brand: brand_acme
Brand API keys are issued by EnfinitOS to the brand's tenant admin via the brand portal. They are scoped read-only to records the brand owns. Disputes are the only write surface and are bound to the brand's own auditor-key signature, not the API key.
Installation
pip install enfinitos-sdk-brand
# or, for tests:
pip install 'enfinitos-sdk-brand[dev]'
Requires Python 3.10+ (pattern matching, structural typing).
Getting started
import asyncio
import os
from enfinitos_brand import EnfinitOSAPIError, EnfinitOSBrandClient
async def main() -> None:
async with EnfinitOSBrandClient(
api_base_url="https://api.enfinitos.com",
brand_id=os.environ["ENFINITOS_BRAND_ID"],
api_key=os.environ["ENFINITOS_BRAND_API_KEY"],
) as client:
# 1. List active campaigns.
page = await client.campaigns.list(status="ACTIVE")
print(f"Brand has {len(page.items)} active campaigns")
for cmp in page.items:
# 2. Pull the signed proof pack + metering summary.
pack = await client.proof.pack(cmp.campaign_id)
summary = await client.metering.summary(cmp.campaign_id)
print(cmp.name, summary.totals)
# 3. Hand the pack to the Auditor SDK to verify the
# signature + Merkle structure.
#
# from enfinitos_auditor import verify_pack
# verdict = await verify_pack(pack)
# if not verdict.ok:
# ... # dispute
# 4. On any 4xx/5xx, the SDK raises a typed error.
try:
await client.campaigns.get("does-not-exist")
except EnfinitOSAPIError as e:
print("API error", e.code, e.correlation_id)
asyncio.run(main())
Module reference
| Namespace | Methods | Purpose |
|---|---|---|
client.campaigns | list, get | Brand-owned campaigns. Read-only. |
client.proof | summary, pack, chain | Signed evidence. Verify with the Auditor SDK. |
client.metering | summary, breakdown | Billable-unit rollups per campaign. |
client.settlement | invoices, invoice, line | Invoices issued to the brand, with per-line proof slices. |
client.disputes | open, list, get | Brand-raised disputes. The SDK's only write surface. |
All methods are async coroutines.
Error model
class EnfinitOSAPIError(Exception):
code: str # "UNAUTHORIZED", "CAMPAIGN_NOT_FOUND", …
http_status: int
correlation_id: str
details: dict | None
is_client_error: bool # @property
is_retryable: bool # @property
class EnfinitOSTransportError(Exception):
cause: BaseException | None
Connection-level failures surface as EnfinitOSTransportError — those never reached the platform and are always safe to retry. The SDK does not retry automatically. Use EnfinitOSAPIError.is_retryable to opt in.
Cross-reference: Auditor SDK
The brand SDK retrieves evidence; the Auditor SDK verifies it. They are deliberately separate packages so the verifier can ship into an air-gapped environment without the HTTP client.
| Brand SDK output | Auditor SDK function |
|---|---|
SignedProofPack | verify_pack(pack) |
ProofRecord + Merkle path | verify_leaf_inclusion(record, path, root) |
InvoiceLine.proof_slice_root | verify_slice(slice, root) |
SignedEvidence (dispute) | verify_evidence(evidence, public_key) |
Status
Initial release. Contract version 1.