Skip to main content

orita-sdk (Python)

PyPI version Python 3.8+ License: MIT

Provider resolution and booking infrastructure for AI applications — Python SDK

Orita searches your provider network, applies license, insurance, modality, and availability constraints, then confirms the booking safely through one API.

API v2 docs: orita.online/developers
API reference: orita.online/developers/reference
Node.js SDK: npmjs.com/package/orita-sdk


Installation

pip install orita-sdk

Requirements: Python 3.8+. Only dependency: requests.


Primary workflow — Provider resolution

Use when you know what the customer needs but not who should handle it.

from orita import OritaClient
import uuid

client = OritaClient(api_key="orita_live_...")

# 1. Resolve — search eligible providers with verified availability
resolution = client.resolutions.create(
    service_id="svc_therapy_initial",
    date_range={"from": "2026-08-05", "to": "2026-08-12"},
    constraints={
        "languageCodes":      {"anyOf": ["es"]},
        "modalityCodes":      {"anyOf": ["virtual"]},
        "licenseRegionCodes": {"anyOf": ["US-NJ"]},
        "insurancePlanCodes": {"anyOf": ["aetna"]},
        "acceptsNewClients":  True,
    },
    preferences={
        "dayParts":         ["afternoon"],
        "earliestAvailable": True,
    },
)

# resolution["options"][0] = top-ranked, explained provider-time option
top = resolution["options"][0]
print(top["reason"])           # "Earliest available; speaks Spanish; accepts virtual visits."
print(top["score"])            # 94

# 2. Inspect candidates (optional — why each provider was included or excluded)
candidates = client.resolutions.list_candidates(resolution["resolutionId"])
for c in candidates["candidates"]:
    print(c["displayName"], c["eligibilityStatus"])

# 3. Hold the chosen option (prevents concurrent booking)
hold = client.resolutions.hold_option(
    resolution["resolutionId"],
    top["optionId"],
    ttl_seconds=120,
)
print(hold["expiresAt"])  # hold expires at this time

# 4. Present provider, service, time, and cancellation policy to customer
# Do not confirm before the customer has approved.

# 5. Confirm — creates the booking atomically
booking = client.resolutions.confirm(
    resolution_id=resolution["resolutionId"],
    option_id=top["optionId"],
    hold_id=hold["holdId"],
    customer={"name": "James Park", "email": "james@example.com"},
    idempotency_key=f"session-{uuid.uuid4()}",
)
print(booking["id"])      # booking UUID
print(booking["status"])  # "confirmed"

Authentication

client = OritaClient(api_key="orita_live_...")

All keys begin with orita_. Test keys (orita_test_...) have identical behavior but do not send real email notifications or trigger live webhooks.


Provider resolution

client.resolutions.create()

resolution = client.resolutions.create(
    service_id="svc_therapy",
    date_range={"from": "2026-08-05", "to": "2026-08-12"},
    constraints={
        # Hard constraints — provider excluded if any fail
        "languageCodes":      {"anyOf": ["es", "en"]},
        "modalityCodes":      {"anyOf": ["virtual"]},
        "specialtyCodes":     {"anyOf": ["anxiety", "cbt"]},
        "licenseRegionCodes": {"anyOf": ["US-NJ"]},
        "insurancePlanCodes": {"anyOf": ["aetna"]},
        "acceptsNewClients":  True,
    },
    preferences={
        # Soft preferences — affect ranking only
        "dayParts":             ["afternoon"],
        "earliestAvailable":    True,
        "continuityProviderId": "pro_...",  # prefer existing provider
    },
    limit=5,
    idempotency_key="session-xyz-resolution-1",
)

Returns a resolution dict with resolutionId, status, options, exclusionSummary, warnings.

client.resolutions.get(resolution_id)

Retrieve a stored resolution by ID.

client.resolutions.list_candidates(resolution_id, status=None, limit=50)

Per-provider eligibility breakdown. status can be "matched", "excluded", or "unknown".

candidates = client.resolutions.list_candidates(
    resolution["resolutionId"],
    status="excluded",  # see why providers were excluded
)
for c in candidates["candidates"]:
    for excl in c["exclusions"]:
        print(f"{c['displayName']}: excluded — {excl['code']} ({excl['field']})")

client.resolutions.hold_option(resolution_id, option_id, ttl_seconds=120)

Hold a slot. Returns holdId, status, expiresAt.

client.resolutions.release_hold(resolution_id, option_id)

Release a hold before it expires. Returns status='released'.

client.resolutions.confirm(resolution_id, option_id, customer, hold_id=None, metadata=None, idempotency_key=None)

Confirm an option and create the booking.

booking = client.resolutions.confirm(
    resolution_id=resolution["resolutionId"],
    option_id=resolution["options"][0]["optionId"],
    hold_id=hold["holdId"],
    customer={"name": "James Park", "email": "james@example.com"},
    idempotency_key="session-xyz-confirm-1",
)

Provider management

# Create a provider
provider = client.providers.create(
    displayName="Dr. Ana García",
    externalId="your-db-id-2841",
    timezone="America/New_York",
    languageCodes=["es", "en"],
    modalityCodes=["virtual"],
    licenseRecords=[{
        "licenseTypeCode": "psychologist",
        "regionCode": "US-NJ",
        "status": "active",
        "expiresAt": "2027-06-30",
    }],
    insurancePlanCodes=["aetna", "cigna"],
    acceptsNewClients=True,
)

# Get a provider
p = client.providers.get(provider["id"])

# Update a provider (increments profileVersion)
client.providers.update(provider["id"], acceptsNewClients=False)

# Check readiness before resolution
readiness = client.providers.readiness(provider["id"])
print(readiness["readiness"])        # 'ready' | 'warning' | 'blocked'
print(readiness["readyForResolution"])  # True/False
for issue in readiness["issues"]:
    print(issue["code"], issue["severity"])

# Deactivate / reactivate
client.providers.deactivate(provider["id"])
client.providers.reactivate(provider["id"])

Bulk provider import

# Dry run — validate without writing
result = client.provider_imports.create(
    providers=[...],  # up to 500
    dry_run=True,
)
print(result["summary"])  # {received, created, updated, failed}

# Commit
job = client.provider_imports.create(providers=[...], mode="upsert")
print(job["importId"])

# Poll status
status = client.provider_imports.get(job["importId"])
print(status["status"])   # 'completed' | 'processing' | 'failed'
print(status["errors"])   # row-level validation errors

Direct scheduling (secondary workflow — v1)

Use when you already know the provider. For unknown-provider matching, use provider resolution above.

# Get available slots
slots = client.slots(event_type_id="evt_abc123", date="2026-08-05")
# [{"id": "slot_...", "label": "3:00 PM", ...}, ...]

# Book directly
booking = client.book(
    slot_id=slots[0]["id"],
    customer={"name": "Ana", "email": "ana@example.com"},
)

# Manage bookings
client.reschedule("booking-uuid", date="2026-08-06", time="10:00")
client.cancel("booking-uuid", reason="Patient requested cancellation")

Error handling

from orita import OritaClient, OritaError, OritaAuthError, OritaNotFoundError, OritaSlotUnavailableError

try:
    booking = client.resolutions.confirm(...)
except OritaSlotUnavailableError:
    # 409 — slot taken by concurrent booking; re-resolve
    resolution = client.resolutions.create(...)
except OritaNotFoundError:
    # 404 — resource not found or cross-tenant access
    pass
except OritaAuthError:
    # 401 — invalid or revoked API key
    pass
except OritaError as e:
    # Other API error
    print(str(e))

Agent safety rules

  • Resolution does not create a booking — call confirm() only after customer approval.
  • Always display provider, service, start time, timezone, and cancellation policy before confirming.
  • Use idempotency_key on every confirm() call for safe retries.
  • Use hold_option() before confirm() to prevent race conditions.

Download files

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

Source Distribution

orita_sdk-0.5.0.tar.gz (11.2 kB view details)

Uploaded Source

Built Distribution

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

orita_sdk-0.5.0-py3-none-any.whl (9.6 kB view details)

Uploaded Python 3

File details

Details for the file orita_sdk-0.5.0.tar.gz.

File metadata

  • Download URL: orita_sdk-0.5.0.tar.gz
  • Upload date:
  • Size: 11.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.3

File hashes

Hashes for orita_sdk-0.5.0.tar.gz
Algorithm Hash digest
SHA256 a1926c84f4a8131bc4869230703ee8b9b2bbc5c9f59d6c4ef0f3a939164d79d3
MD5 f033a3a19cc6d5491781e57047b790af
BLAKE2b-256 01b0746887fb65ca1b0a2ea8969d73f15bbc8514999b77500c8e41c3f12c4f47

See more details on using hashes here.

File details

Details for the file orita_sdk-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: orita_sdk-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 9.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.14.3

File hashes

Hashes for orita_sdk-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e26ce2cb4ce283c18e38fe389fa9338809dc2ca535a94f9f519d5836ae6a6b51
MD5 a47daac663d2e14e0639445bbe4bf4a4
BLAKE2b-256 e218f4e978cbe28fe92175f90ad026959f48f1a18e8117b038208723675149a4

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.5.0 This release

2 files

0.4.1

2 files

0.4.0

2 files

0.3.1

2 files

0.3.0

2 files

0.2.1

2 files

0.2.0

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page