NLPearl Python Wrapper
NLPearl is a Python wrapper for the NLPearl API, allowing developers to interact seamlessly with NLPearl's services. This package supports both API V1 and V2 with a unified interface.
Table of Contents
- Installation
- Getting Started
- Quick Start
- API Versions
- Usage Guide
- Complete API Reference
- Migration Guide
- Changelog
- License
Installation
pip install nlpearl
Getting Started
- Get your API key from NLPearl
- Set your API version (V2 is default)
- Start making API calls!
import os
import nlpearl as pearl
from dotenv import load_dotenv
# Configuration
load_dotenv()
env = os.environ
pearl.api_key = env["PROD_API_KEY"]
pearl.api_version = "v2" # Default, can be "v1" or "v2"
Quick Start
V2 Example (Default)
import os
import nlpearl as pearl
from dotenv import load_dotenv
load_dotenv()
pearl.api_key = os.environ["PROD_API_KEY"]
pearl.api_version = "v2" # Default
# Get all pearls
pearls = pearl.Pearl.get_all()
# Add a lead using pearl_id
pearl.Outbound.add_lead(
pearl_id,
phone_number="+1234567890",
call_data={"firstName": "John"}
)
# Get analytics
analytics = pearl.Pearl.get_analytics(
pearl_id,
from_date="2024-01-01T00:00:00.000Z",
to_date="2024-01-31T23:59:59.999Z"
)
V1 Example
import os
import nlpearl as pearl
from dotenv import load_dotenv
load_dotenv()
pearl.api_key = os.environ["PROD_API_KEY"]
pearl.api_version = "v1"
# Get all inbounds
inbounds = pearl.Inbound.get_all()
# Add a lead using outbound_id
pearl.Outbound.add_lead(
outbound_id,
phone_number="+1234567890",
call_data={"firstName": "John"}
)
# Get analytics
analytics = pearl.Outbound.get_analytics(
outbound_id,
from_date="2024-01-01T00:00:00.000Z",
to_date="2024-01-31T23:59:59.999Z"
)
API Versions
The wrapper uses the same class names for both V1 and V2, automatically routing to the correct endpoints based on pearl.api_version.
Version Differences
| Feature | V1 | V2 |
|---|---|---|
| Default | No | Yes |
| Structure | Separate Inbound/Outbound | Unified Pearl |
| ID Parameter | outbound_id, inbound_id |
pearl_id |
| Classes | Inbound, Outbound |
Pearl |
| Lead Operations | Outbound.add_lead(outbound_id, ...) |
Outbound.add_lead(pearl_id, ...) |
| Total Endpoints | 26 | 26 |
Unified API Approach
- Same class names - Use
pearl.Outbound,pearl.Pearl,pearl.Inbound - Automatic routing - Methods route to correct version based on
api_version - Clear errors - Helpful messages when using wrong version
- Version switching - Change
api_versionanytime
No separate V2 classes needed! Just set the version once and use the same API.
Usage Guide
V2 API (Default)
Account Operations (V2)
pearl.api_version = "v2"
# Get account info (works in both V1 and V2)
account = pearl.Account.get_account()
# V2-only account methods
users = pearl.Account.get_users() # Get list of users
phones = pearl.Account.get_phone_numbers() # Get active phone numbers
voices = pearl.Account.get_voices() # Get available voices by language
channels = pearl.Account.get_text_channels() # SMS/WhatsApp channels for text pearls
# Audit log
logs = pearl.Account.get_audit_log(
from_date=datetime(2024, 1, 1),
to_date=datetime(2024, 1, 31),
event_type=10, # Optional: 10 = PublishPearl
user_id=None # Optional: filter on a single user
)
# Blacklist: full numbers or prefixes ("+41" blocks all of Switzerland)
blacklist = pearl.Account.search_blacklist(skip=0, limit=50, search="+41")
pearl.Account.add_to_blacklist(["+1234567890", "+41837"])
pearl.Account.remove_from_blacklist(["+1234567890"])
Call Recordings (V2)
# Download the audio of a call
audio = pearl.Recording.get_recording(client_id, pearl_id, call_id)
# Or write it straight to a file
pearl.Recording.save_recording(client_id, pearl_id, call_id, "call.ogg")
# Build the URL without downloading
url = pearl.Recording.get_url(client_id, pearl_id, call_id)
Pearl Management (V2)
pearl.api_version = "v2"
# Get all pearls
pearls = pearl.Pearl.get_all()
# Get specific pearl
pearl_details = pearl.Pearl.get(pearl_id)
# Create a new pearl
new_pearl = pearl.Pearl.create(
name="My Pearl",
pearl={"businessName": "My Company", "objective": "Sales"},
variables=[{"name": "firstName", "description": "Customer first name"}],
inbound={"isActive": True},
outbound={"isActive": True, "callerIdNumber": "+1234567890"}
)
# Update pearl settings
pearl.Pearl.update(
pearl_id,
name="Updated Pearl Name",
pearl={"businessName": "New Name"}
)
# Get pearl settings. The returned agentType tells you which update method to use:
# 1 = Voice, 2 = Text; a Simple Pearl uses update(), a node graph uses update_voice/text().
settings = pearl.Pearl.get_settings(pearl_id)
# Node-graph pearls: the conversation is a graph of nodes connected by transitions,
# instead of an opening sentence + flow script.
voice_pearl_id = pearl.Pearl.create_voice(
name="My Voice Pearl",
pearl={
"agentPersonality": "Friendly",
"timeZone": "Romance Standard Time",
"companyName": "My Company",
"nodes": [...], # Needs one OpeningSentence and one EndCall node
},
outbound={"phoneNumberId": phone_id, "totalAgents": 1}
)
text_pearl_id = pearl.Pearl.create_text(
name="My Text Pearl",
pearl={"companyName": "My Company", "nodes": [...]},
inbound={"textChannelId": channel_id} # From Account.get_text_channels()
)
# On update, pearl replaces the WHOLE graph while inbound/outbound are partial updates.
pearl.Pearl.update_voice(voice_pearl_id, name="Renamed", outbound={"totalAgents": 2})
pearl.Pearl.update_text(text_pearl_id, pearl={"nodes": [...]})
# Credentials usable as credentialId of an API action in the flow
credentials = pearl.Pearl.get_credentials(pearl_id)
# Update outbound/inbound settings
pearl.Pearl.update_outbound_settings(pearl_id, {"callerIdNumber": "+1234567890"})
pearl.Pearl.update_inbound_settings(pearl_id, {"isActive": True})
# Activate/Deactivate
pearl.Pearl.set_active(pearl_id, is_active=True)
# Get ongoing calls
ongoing = pearl.Pearl.get_ongoing_calls(pearl_id)
# Get calls with filters
calls = pearl.Pearl.get_calls(
pearl_id,
from_date=datetime(2024, 1, 1),
to_date=datetime(2024, 1, 31),
tags=["important"],
statuses=[100, 130],
search_input="John"
)
# Same filters, but opt into extra fields: only what you ask for is returned
calls = pearl.Pearl.get_calls_bulk(
pearl_id,
from_date=datetime(2024, 1, 1),
to_date=datetime(2024, 1, 31),
fields=["Summary", "Transcript", "Recording", "PearlVersion"]
)
# Get analytics
analytics = pearl.Pearl.get_analytics(pearl_id, from_date, to_date)
# Reset customer memory
pearl.Pearl.reset_memory(pearl_id, phone_number="+1234567890")
Lead Management (V2)
# Add lead (using pearl_id, uses POST in V2)
lead = pearl.Outbound.add_lead(
pearl_id,
phone_number="+1234567890",
external_id="ext123",
time_zone_id="Pacific Standard Time",
call_data={"firstName": "John", "lastName": "Doe"}
)
# Add many leads at once (V2 only, max 50,000 per call)
pearl.Outbound.add_leads(pearl_id, [
{"phoneNumber": "+1234567890", "externalId": "ext123"},
{"phoneNumber": "+1234567891", "callData": {"firstName": "Jane"}}
])
# Get lead
lead = pearl.Outbound.get_lead_by_id(pearl_id, lead_id)
lead = pearl.Outbound.get_lead_by_external_id(pearl_id, "ext123")
lead = pearl.Outbound.get_lead_by_phone_number(pearl_id, "+1234567890")
# Update lead
pearl.Outbound.update_lead(
pearl_id,
lead_id,
status=100, # Mark as Success
call_data={"notes": "Contact successful"}
)
# Search leads
leads = pearl.Outbound.get_leads(
pearl_id,
statuses=[1, 10], # New and NeedRetry
search_input="John",
limit=50
)
# Delete leads
pearl.Outbound.delete_leads(pearl_id, [lead_id1, lead_id2])
pearl.Outbound.delete_leads_by_external_id(pearl_id, ["ext1", "ext2"])
V1 API
Account Operations (V1)
pearl.api_version = "v1"
# Get account info
account = pearl.Account.get_account()
Inbound Operations (V1 Only)
pearl.api_version = "v1"
# Get all inbounds
inbounds = pearl.Inbound.get_all()
# Get specific inbound
inbound = pearl.Inbound.get(inbound_id)
# Activate/Deactivate
pearl.Inbound.set_active(inbound_id, is_active=True)
# Get ongoing calls
ongoing = pearl.Inbound.get_ongoing_calls(inbound_id)
# Get calls with filters
calls = pearl.Inbound.get_calls(
inbound_id,
from_date=datetime(2024, 1, 1),
to_date=datetime(2024, 1, 31),
tags=["important"],
statuses=[100, 130],
search_input="John"
)
# Get analytics
analytics = pearl.Inbound.get_analytics(inbound_id, from_date, to_date)
Outbound Operations (V1)
# Get all outbounds
outbounds = pearl.Outbound.get_all()
# Get specific outbound
outbound = pearl.Outbound.get(outbound_id)
# Activate/Deactivate
pearl.Outbound.set_active(outbound_id, is_active=True)
# Get calls with filters
calls = pearl.Outbound.get_calls(
outbound_id,
from_date=datetime(2024, 1, 1),
to_date=datetime(2024, 1, 31),
statuses=[100, 130],
search_input="John"
)
# Make a call
result = pearl.Outbound.make_call(
outbound_id,
to="+1234567890",
call_data={"firstName": "Jane"}
)
# Get call requests
requests = pearl.Outbound.get_call_requests(
outbound_id,
from_date=datetime(2024, 1, 1),
to_date=datetime(2024, 1, 31)
)
# Get specific call request
request = pearl.Outbound.get_call_request(request_id)
# Get analytics
analytics = pearl.Outbound.get_analytics(outbound_id, from_date, to_date)
Lead Management (V1)
# Add lead (using outbound_id, uses PUT in V1)
lead = pearl.Outbound.add_lead(
outbound_id,
phone_number="+1234567890",
external_id="ext123",
call_data={"firstName": "John"}
)
# Update lead
pearl.Outbound.update_lead(outbound_id, lead_id, status=100)
# Search leads
leads = pearl.Outbound.get_leads(
outbound_id,
statuses=[1, 10], # Array of status codes
search_input="John"
)
# Other lead methods work the same
lead = pearl.Outbound.get_lead_by_id(outbound_id, lead_id)
pearl.Outbound.delete_leads(outbound_id, [lead_id1, lead_id2])
Shared Methods
These methods work in both V1 and V2:
Account
# Works in both versions
account = pearl.Account.get_account()
print(f"Balance: {account['creditBalance']}")
Call Operations
# Get call info (both versions)
call = pearl.Call.get_call(call_id)
# Delete calls (both versions)
pearl.Call.delete_calls([call_id1, call_id2])
Memory Management
# V1 and V2 (different implementations internally)
pearl.Pearl.reset_customer_memory(pearl_id, phone_number)
# V2 alias
pearl.Pearl.reset_memory(pearl_id, phone_number)
Complete API Reference
V1 Endpoints (26 total)
| Class | Method | Description |
|---|---|---|
| Account | get_account() |
Get account information |
| Call | get_call(call_id) |
Get call details |
| Call | delete_calls(call_ids) |
Delete multiple calls |
| Inbound | get_all() |
List all inbound pearls |
| Inbound | get(inbound_id) |
Get specific inbound |
| Inbound | set_active(inbound_id, is_active) |
Activate/deactivate |
| Inbound | get_calls(inbound_id, ...) |
Get calls with filters |
| Inbound | get_ongoing_calls(inbound_id) |
Get active calls |
| Inbound | get_analytics(inbound_id, ...) |
Get analytics data |
| Outbound | get_all() |
List all outbound pearls |
| Outbound | get(outbound_id) |
Get specific outbound |
| Outbound | set_active(outbound_id, is_active) |
Activate/deactivate |
| Outbound | get_calls(outbound_id, ...) |
Get calls with filters |
| Outbound | get_analytics(outbound_id, ...) |
Get analytics data |
| Outbound | make_call(outbound_id, to, call_data) |
Initiate a call |
| Outbound | get_call_request(request_id) |
Get call request status |
| Outbound | get_call_requests(outbound_id, ...) |
List call requests |
| Outbound | add_lead(outbound_id, ...) |
Add lead (uses PUT) |
| Outbound | update_lead(outbound_id, lead_id, ...) |
Update lead |
| Outbound | get_leads(outbound_id, ...) |
List leads with filters |
| Outbound | get_lead_by_id(outbound_id, lead_id) |
Get lead by ID |
| Outbound | get_lead_by_external_id(outbound_id, ext_id) |
Get lead by external ID |
| Outbound | get_lead_by_phone_number(outbound_id, phone) |
Get lead by phone |
| Outbound | delete_leads(outbound_id, lead_ids) |
Delete leads by ID |
| Outbound | delete_leads_by_external_id(outbound_id, ext_ids) |
Delete by external ID |
| Pearl | reset_customer_memory(pearl_id, phone) |
Reset memory (URL param) |
V2 Endpoints (26 total)
| Class | Method | Description |
|---|---|---|
| Account | get_account() |
Get account information |
| Account | get_users() |
Get list of users [NEW] |
| Account | get_phone_numbers() |
Get active phone numbers [NEW] |
| Account | get_voices() |
Get available voices [NEW] |
| Call | get_call(call_id) |
Get call details |
| Call | delete_calls(call_ids) |
Delete multiple calls |
| Pearl | get_all() |
List all pearls |
| Pearl | get(pearl_id) |
Get specific pearl |
| Pearl | create(name, pearl, ...) |
Create new pearl [NEW] |
| Pearl | update(pearl_id, ...) |
Update pearl [NEW] |
| Pearl | set_active(pearl_id, is_active) |
Activate/deactivate |
| Pearl | get_calls(pearl_id, ...) |
Get calls with filters |
| Pearl | get_ongoing_calls(pearl_id) |
Get active calls |
| Pearl | get_analytics(pearl_id, ...) |
Get analytics data |
| Pearl | get_settings(pearl_id) |
Get pearl settings [NEW] |
| Pearl | update_outbound_settings(pearl_id, settings) |
Update outbound [NEW] |
| Pearl | update_inbound_settings(pearl_id, settings) |
Update inbound [NEW] |
| Pearl | reset_memory(pearl_id, phone) |
Reset memory (body) |
| Outbound | add_lead(pearl_id, ...) |
Add lead (uses POST) |
| Outbound | update_lead(pearl_id, lead_id, ...) |
Update lead |
| Outbound | get_leads(pearl_id, ...) |
List leads with filters |
| Outbound | get_lead_by_id(pearl_id, lead_id) |
Get lead by ID |
| Outbound | get_lead_by_external_id(pearl_id, ext_id) |
Get lead by external ID |
| Outbound | get_lead_by_phone_number(pearl_id, phone) |
Get lead by phone |
| Outbound | delete_leads(pearl_id, lead_ids) |
Delete leads by ID |
| Outbound | delete_leads_by_external_id(pearl_id, ext_ids) |
Delete by external ID |
Method Availability Matrix
| Class | Method | V1 | V2 | Notes |
|---|---|---|---|---|
| Account | get_account() |
Y | Y | Shared |
| Account | get_users() |
- | Y | V2 only |
| Account | get_phone_numbers() |
- | Y | V2 only |
| Account | get_voices() |
- | Y | V2 only |
| Call | get_call(call_id) |
Y | Y | Shared |
| Call | delete_calls(call_ids) |
Y | Y | Shared |
| Inbound | All methods | Y | - | V1 only |
| Outbound | get_all() |
Y | - | V1 only |
| Outbound | get(id) |
Y | - | V1 only |
| Outbound | set_active(...) |
Y | - | V1 only |
| Outbound | get_calls(...) |
Y | - | V1 only |
| Outbound | get_analytics(...) |
Y | - | V1 only |
| Outbound | make_call(...) |
Y | - | V1 only |
| Outbound | get_call_request(...) |
Y | - | V1 only |
| Outbound | get_call_requests(...) |
Y | - | V1 only |
| Outbound | Lead methods | Y | Y | Shared (different ID) |
| Pearl | get_all() |
- | Y | V2 only |
| Pearl | get(pearl_id) |
- | Y | V2 only |
| Pearl | create(...) |
- | Y | V2 only |
| Pearl | update(...) |
- | Y | V2 only |
| Pearl | set_active(...) |
- | Y | V2 only |
| Pearl | get_calls(...) |
- | Y | V2 only |
| Pearl | get_ongoing_calls(...) |
- | Y | V2 only |
| Pearl | get_analytics(...) |
- | Y | V2 only |
| Pearl | get_settings(...) |
- | Y | V2 only |
| Pearl | update_outbound_settings(...) |
- | Y | V2 only |
| Pearl | update_inbound_settings(...) |
- | Y | V2 only |
| Pearl | reset_customer_memory(...) |
Y | Y | Different implementation |
Status Codes
Lead Status
1- New10- NeedRetry100- Success110- NotSuccessful130- Completed150- Unreachable220- Blacklisted500- Error
Call Status
3- InProgress4- Completed5- Busy6- Failed7- NoAnswer8- Canceled
Activity Status
1- Running2- Paused3- Suspended10- TemporaryMaintenance
Migration Guide
From V1 to V2
Before (V1):
pearl.api_version = "v1"
# Get outbounds
outbounds = pearl.Outbound.get_all()
# Add lead
pearl.Outbound.add_lead(outbound_id, phone_number="+123...")
# Get analytics
analytics = pearl.Outbound.get_analytics(outbound_id, from_date, to_date)
After (V2):
pearl.api_version = "v2"
# Get pearls (replaces outbounds/inbounds)
pearls = pearl.Pearl.get_all()
# Add lead (same method, different ID)
pearl.Outbound.add_lead(pearl_id, phone_number="+123...")
# Get analytics (use Pearl class)
analytics = pearl.Pearl.get_analytics(pearl_id, from_date, to_date)
Key Changes
- Replace
outbound_id/inbound_idwithpearl_id - Use
Pearlclass for analytics, calls, and pearl management - Keep using
Outboundfor lead operations (just change the ID) Inboundclass is V1-only, usePearlin V2
Error Handling
The wrapper provides clear error messages when using methods in the wrong version:
pearl.api_version = "v2"
pearl.Inbound.get_all()
# ValueError: Inbound.get_all() is only available in API v1.
# In v2, use Pearl.get_all() instead.
Changelog
Version 2.0.0 (February 2026)
API Versioning System
- Added
pearl.api_versionglobal variable (default: 'v2') - Added
_get_api_url()helper for dynamic URL generation - Unified API: Same class names work for both V1 and V2
New V2 Account Endpoints
Account.get_users()- Get list of usersAccount.get_phone_numbers()- Get active phone numbersAccount.get_voices()- Get available voices by language
New V2 Pearl Endpoints
Pearl.create()- Create a new Pearl with full configurationPearl.update()- Update Pearl settingsPearl.get_settings()- Get Pearl configurationPearl.update_outbound_settings()- Update outbound settingsPearl.update_inbound_settings()- Update inbound settings
V1 Fixes (from OpenAPI spec)
Outbound.get_calls()- Addedstatuses(array),search_inputparametersOutbound.get_leads()- Changedstatustostatuses(array), addedsearch_inputInbound.get_calls()- Addedstatuses(array),search_inputparameters
Version-Specific Behavior
Outbound.add_lead(): V1 uses PUT, V2 uses POSTPearl.reset_customer_memory(): V1 uses URL param, V2 uses request body- Methods raise
ValueErrorif called with wrong API version
License
BSD 3-Clause License - see LICENSE file for details.
Contact
- Support: support@nlpearl.ai
- Documentation: This README
- API Key: Contact support@nlpearl.ai
Version: 2.0.0
Python: 3.6+
API Versions: V1 (26 endpoints) and V2 (26 endpoints) supported
Release files for nlpearl 2.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| nlpearl-2.2.0.tar.gz | 23.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| nlpearl-2.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 46.5 kB
Release files / nlpearl-2.2.0.tar.gz
| Download URL | nlpearl-2.2.0.tar.gz |
|---|---|
| Size | 23.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d071f8fa0befeae9521197723e53c7a06a06d0acedb4221bf638ee30b0054a8f
|
|
BLAKE2b-256 checksum How to use checksums |
fcb7a04fd91c2857b868ccc5457796d5d14bf0494c77d1ec6a9aa4290e96c092
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/5.1.1 CPython/3.9.13
|
Release files / nlpearl-2.2.0-py3-none-any.whl
| Download URL | nlpearl-2.2.0-py3-none-any.whl |
|---|---|
| Size | 23.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7da7b0dc4b6b613f6d9a5aad954260ad542b722dc281600b603bff73cd5e74f6
|
|
BLAKE2b-256 checksum How to use checksums |
03d3005e0b7d9ec3289f68489bb7abbebf6acde8f635b4054d170308d830c9bb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/5.1.1 CPython/3.9.13
|