Catalog PyPI
PACKAGE EXPLORERView in registry

afini-twin-sdk

PyPI

Official Python SDK for the AfiniTwin B2B API.

afiniafinitwinaibig-fivecognitive-profileipip-neollmpersonalitysystem-prompt
Versions collected1
Direct dependencies2From release 0.1.0
Last observed20 Oct, 21:06 UTC

README

Version 0.1.0 documentation

afini-twin-sdk

Official Python SDK for the AfiniTwin B2B API.

The AfiniTwin is a portable cognitive profile (Big Five + 5 supplementary layers) built on the Afini.ai platform. This SDK gives you typed access to a user's snapshot from your own systems — CRMs, custom assistants, internal pipelines.

Installation

pip install afini-twin-sdk

Requires Python ≥ 3.10. Built on httpx and pydantic v2.

Get an API key

Active users with a Professional plan on Afini.ai can generate keys at afini.ai/dashboard/twin/api. The key is shown once — store it securely.

Quick start

Async

import asyncio
import os
from afini_twin import AfiniTwinClient

async def main():
    async with AfiniTwinClient(api_key=os.environ["AFINITWIN_KEY"]) as client:
        me = await client.me()
        print(f"User has {me['twins']['ready']} ready snapshots; quota {me['quota']['remaining']}/{me['quota']['monthlyLimit']}")

        snapshots = await client.historic()
        for s in snapshots["snapshots"]:
            print(s["id"], s["snapshotDate"])

        # Download standard preset as Markdown
        md = await client.preset("estandar", format="md", lang="es")
        print(md[:200], "…")

asyncio.run(main())

Sync

from afini_twin import AfiniTwinSyncClient

with AfiniTwinSyncClient(api_key=os.environ["AFINITWIN_KEY"]) as client:
    me = client.me()

Sending data into the user's profile (twin:write scope)

If your API key has the twin:write scope, you can seed life-facts and annotations. They go to the user's review queue at /dashboard/discoveries; nothing is injected into the profile until the user approves.

from afini_twin import AfiniTwinClient, LifeFactInput

async with AfiniTwinClient(api_key=os.environ["AFINITWIN_KEY"]) as client:
    result = await client.life_facts_create([
        LifeFactInput(
            category="professional",
            value="Trabaja en una startup de IA en Bilbao desde 2023",
            valence="positive",
            consent=True,
            external_ref="crm-12345",
        )
    ])
    print(result["accepted"], "candidates queued ->", result["inboxUrl"])

For free-form notes:

from afini_twin import AnnotationInput

await client.annotations_create([
    AnnotationInput(tag="observation", text="Mostró interés por escalar a Pro", consent=True)
])

The pydantic models reject consent != True at validation time — you can't accidentally submit without an explicit confirmation.

Verifying webhook signatures

Every webhook POST carries an X-AfiniTwin-Signature: sha256=<hmac> header. Verify before trusting the payload:

FastAPI

from fastapi import FastAPI, Request, HTTPException
from afini_twin import verify_webhook_signature

app = FastAPI()
SECRET = os.environ["AFINITWIN_WEBHOOK_SECRET"]

@app.post("/webhooks/afinitwin")
async def afinitwin_hook(request: Request):
    raw = await request.body()
    sig = request.headers.get("x-afinitwin-signature")
    if not verify_webhook_signature(raw, sig, SECRET):
        raise HTTPException(403)
    payload = await request.json()
    if payload["event"] == "twin.snapshot.ready":
        # … pull the new snapshot
        pass
    elif payload["event"] == "twin.quota.exceeded":
        # … alert your billing
        pass
    return {"ok": True}

Django / Flask

The function is framework-agnostic: pass the raw body (bytes or str) plus the header value plus the secret.

Error handling

from afini_twin import AfiniTwinClient, AfiniTwinApiError

try:
    async with AfiniTwinClient(api_key=key) as client:
        await client.me()
except AfiniTwinApiError as e:
    if e.status == 429 and e.body and e.body.get("code") == "TIER_QUOTA_EXCEEDED":
        # upgrade your B2B tier
        ...
    raise

Rate limits

Endpoint groupPer minutePer month
/health120unlimited
/me, /historic, /snapshots/*, /preset/*60per tier
/life-facts, /annotations30per tier

The monthly cap is enforced per user across all keys based on the B2B tier (Included = 10k, Starter = 100k, Pro = 1M, Enterprise = custom).

License

MIT © Bilbao AI S.L.

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Versions 1

Collected releases
VersionPublishedDirect dependenciesOpen version
0.1.010 May 20262

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
ricardodevis/afini-twin-sdk-py

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 21:06 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:dd20d9ed97bb37483567f3849765e60262c6b6cbd5cd97ea3bbf129183e48d2b