Skip to main content

Ravi SDK — Python client for the Ravi identity API

Project description

ravi

The Python SDK for Ravi — the identity provider for AI agents.

pip install ravi-sdk
import os
from ravi import Ravi

# Keys are ravi_id_... (scoped to one identity) or ravi_mgmt_... (account-wide).
# The key is an auth FENCE only — the caller chooses the identity, and every
# per-identity call carries ?identity=<uuid> taken from the identity object.
ravi = Ravi(api_key=os.environ["RAVI_API_KEY"])

# Create an identity. The email address is an identifier (local part) plus an
# optional domain; omit both to auto-generate. provision_phone adds a number.
identity = ravi.identities.create(email_identifier="support-agent", provision_phone=True)
print(identity.email.address, identity.phone.number)   # support-agent@... , +1...

# `email` and `phone` are channel objects, not strings. Comms, vault, and
# contacts are reached ONLY through the identity — never off the client.
identity.email.send(to="user@example.com", subject="Hello", body="Greetings from my AI agent")
msg = identity.email.wait_for(lambda m: "verify" in m.subject)   # poll the inbox
msg.reply(body="got it")                                         # messages are client-bound

identity.phone.send(to="+15551234567", body="START")
otp = identity.phone.wait_for(lambda m: "code" in m.body, timeout=120)

# Place an outbound voice call from the identity's number.
call = identity.phone.call(to="+15551234567")
print(call.uuid, call.status)
transcript = call.transcript()

# Credentials live in the identity's vault.
identity.vault.passwords.create(domain="acme.com", username="agent", password="...")
identity.vault.secrets.create(key="OPENAI_API_KEY", value="sk-...")

# Replay events — the deploy-safe companion to the wss://<host>/ws/events/ stream.
for event in identity.events.list(since=0, event_types=["call.ended", "email.message.received"]):
    print(event.seq, event.type, event.data)

# With an identity-scoped key, `ravi.me` resolves the single fenced identity.
me = ravi.me

The SDK talks to Ravi's hosted API. The API host is built into the client.

Status

Getting an API key

Mint a key one of three ways, then pass it as Ravi(api_key=...) (or set RAVI_API_KEY):

  • ravi auth login with the Ravi CLI (one-time human sign-in, then agents self-serve),
  • POST /api/auth/keys/management/ from an authenticated session, or
  • the dashboard at /dashboard/api-keys/.

Keys are ravi_mgmt_... (account-wide) or ravi_id_... (scoped to one identity).

Resources

The API key is an auth fence only. Account-level resources hang off the client; everything per-identity is reached through an Identity and scoped with ?identity=<uuid>.

Account-level (ravi.*)

Accessor Endpoints
ravi.identities identity bundles + provision_phone + voice_agent
ravi.me the single identity an identity-key is fenced to
ravi.events durable account-wide event replay (list(since=...))
ravi.domains verified domains (read-only)
ravi.webhooks subscriptions + deliveries log
ravi.api_keys management + identity keys

Per-identity (identity.*)

Accessor Surface
identity.email .address, inbox/threads/get/send/wait_for (returns EmailMessage)
identity.phone .number, inbox/conversations/send/call/calls/wait_for (or None)
identity.contacts directory + find + search
identity.vault.passwords website credentials + generate
identity.vault.secrets key/value secrets
identity.events this identity's event replay

Messages are client-bound: EmailMessage has .reply/.reply_all/.forward/ .mark_read (and a .body property); SmsMessage has .reply/.mark_read; Call has .hangup/.transcript.

Verifying inbound webhooks

Ravi signs each webhook with X-Ravi-Timestamp + X-Ravi-Signature: sha256=<hex> over "{timestamp}.{raw_body}". Verify against the raw body:

from ravi import verify_webhook_signature, WebhookSignatureError

try:
    verify_webhook_signature(
        raw_body,                       # bytes/str, exactly as received
        request.headers["X-Ravi-Timestamp"],
        request.headers["X-Ravi-Signature"],
        signing_secret,                 # from the webhook subscription
    )
except WebhookSignatureError as exc:
    ...  # reject: exc.code is "invalid_header" | "expired" | "signature_mismatch"

License

Apache 2.0.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ravi_sdk-0.3.0.tar.gz (86.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ravi_sdk-0.3.0-py3-none-any.whl (43.0 kB view details)

Uploaded Python 3

File details

Details for the file ravi_sdk-0.3.0.tar.gz.

File metadata

  • Download URL: ravi_sdk-0.3.0.tar.gz
  • Upload date:
  • Size: 86.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for ravi_sdk-0.3.0.tar.gz
Algorithm Hash digest
SHA256 4ecd306f8b1da48b05dc32e387c6b34838233d7ccee8ffb22b18a9412af7b69e
MD5 a31e438e1861e74940a0080ea8552eff
BLAKE2b-256 2e9d2dd498a0ce27bb2a05f1f8b90d34be1a3570bada4c0d45252b7a820a1cfa

See more details on using hashes here.

File details

Details for the file ravi_sdk-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: ravi_sdk-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 43.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for ravi_sdk-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 813b6b1f835c11c16471bc72e8c053ff25fc16e3c2f4c5b075b150629d5da184
MD5 07b51e0bc4daf6707b28b01dd7be5b7e
BLAKE2b-256 521b19158f7f8be3c09d554dd233471bb7fbc267546c78ab1ec33023c5726683

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page