Python SDK

Install

pip install ravi-sdk

Create A Client

import os
from ravi import Ravi

ravi = Ravi(api_key=os.environ["RAVI_API_KEY"])

api_key is required. Use a ravi_id_... identity key for agent runtime work, or a ravi_mgmt_... management key for account-level operations. The key is an auth fence only — the caller chooses the identity, and every per-identity call sends ?identity=<uuid> taken from the identity object.

For long-running processes, use the context manager so the underlying HTTP pool is closed:

with Ravi(api_key=os.environ["RAVI_API_KEY"]) as ravi:
    identities = ravi.identities.list()

Choose An Identity

The caller chooses the identity, then calls channels and resources on it. Create one, fetch one by uuid, or — with an identity-scoped key — resolve the single fenced identity with ravi.me.

identity = ravi.identities.create(
    name="shopping-agent",
    email_identifier="shopping",   # email local part; omit to auto-generate
    provision_phone=True,          # also give it a phone number
)

# `email` and `phone` are channel objects — the identifiers are `.address` / `.number`.
print(identity.email.address, identity.phone.number)

# With an identity-scoped key you don't have the uuid handy:
me = ravi.me   # the single identity the key is fenced to

Identity methods:

MethodPurpose
ravi.identities.create(...)Create an identity, optionally with email local part and phone provisioning
ravi.identities.list()List identities visible to the key
ravi.identities.get(identity_uuid)Fetch one identity
ravi.identities.update(identity_uuid, name=...)Update identity metadata
ravi.identities.provision_phone(identity_uuid)Add a phone number to an existing identity

Wait For A Verification Code

The killer use case: send a request, then block until the OTP or verification message lands. wait_for polls the channel’s inbox and returns the first matching message.

# Email verification: trigger a signup, then wait for the confirmation email.
identity.email.send(to="signup@service.com", subject="Sign me up", body="…")
msg = identity.email.wait_for(lambda m: "verify" in m.subject, timeout=120)
msg.reply(body="got it")            # messages carry behaviour: reply/forward/mark_read

# SMS OTP: wait for the 6-digit code on the identity's number.
identity.phone.send(to="+15551234567", body="START")
otp = identity.phone.wait_for(lambda m: "code" in m.body, timeout=120)
print(otp.body)

Email Channel

identity.email is the identity’s inbox as a channel. Send from it, list the flat inbox or the grouped threads, and act on returned EmailMessage objects.

msg = identity.email.send(to="user@example.com", subject="Hello", body="Greetings from my AI agent")

inbox = identity.email.inbox(unread=True)   # flat list of EmailMessage
threads = identity.email.threads()          # grouped view

msg.reply(body="Thanks!")
msg.forward(to="ops@acme.com")
msg.mark_read()

Phone Channel

identity.phone is the identity’s number as a channel (or None if no number is provisioned). Send SMS, list conversations, or place voice calls.

sms = identity.phone.send(to="+15551234567", body="Your code is 482910")

inbox = identity.phone.inbox(unread=True)   # flat list of SmsMessage
conversations = identity.phone.conversations()

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

Vault And Contacts

Credentials and the contact directory live under the identity.

identity.vault.passwords.create(domain="acme.com", username="agent", password="…")
identity.vault.secrets.create(key="OPENAI_API_KEY", value="sk-…")

contact = identity.contacts.find("user@example.com")

Events

Replay durable events after your last processed cursor:

events = ravi.events.list(
    since=last_seq,
    limit=100,
    event_types=["call.ended", "email.message.received"],
)

API Keys

Management keys and identity keys are available through ravi.api_keys.

management_key = ravi.api_keys.management.create("ci")
print(management_key.key)  # full value is returned once

identity_key = ravi.api_keys.identity.create("shopping-agent", identity.uuid)
print(identity_key.key)  # full value is returned once

Webhook Verification

Ravi signs deliveries with X-Ravi-Timestamp and X-Ravi-Signature.

from ravi import verify_webhook_signature, WebhookSignatureError

try:
    verify_webhook_signature(
        raw_body,
        request.headers["X-Ravi-Timestamp"],
        request.headers["X-Ravi-Signature"],
        signing_secret,
    )
except WebhookSignatureError:
    return Response(status_code=401)

Public Exports

The PyPI package is ravi-sdk. The Python import module is ravi.

The module exports the Ravi client, resource classes, Pydantic models, typed errors, event payload models, and webhook verification helpers from ravi.

Top-level exports include Ravi, RaviError subclasses, resource classes, Pydantic API models, verify_webhook_signature, and WebhookSignatureError.

Next Steps