Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.13.0"
".": "0.14.0"
}
4 changes: 2 additions & 2 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 19
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/prelude/prelude-bceac2d798eb515f8fd14406ac6f50de2aa983a3674cecb63167c0d0d52cfbc9.yml
openapi_spec_hash: b9963276e8c0178b0c45bf2ea07f63fb
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/prelude/prelude-86fc45f417e6468f6a6087f9e35b264b0a350e31385bc078a2027a1f1abd1d15.yml
openapi_spec_hash: fb72aba38ec55a3b6b5162c9f5b4228d
config_hash: 3dbe79c14ecd9a153418249f9155d159
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
# Changelog

## 0.14.0 (2026-09-15)

Full Changelog: [v0.13.0...v0.14.0](https://github.com/prelude-so/python-sdk/compare/v0.13.0...v0.14.0)

### Features

* **api:** api update ([dbe97f6](https://github.com/prelude-so/python-sdk/commit/dbe97f6119990b49754989c0d73418661fc34f39))
* **api:** api update ([a26c822](https://github.com/prelude-so/python-sdk/commit/a26c8229337934a3d8aa9538c3f77aed50e27946))
* **api:** api update ([0cb1485](https://github.com/prelude-so/python-sdk/commit/0cb148510657037c636847d21929c1c104a45a70))


### Chores

* **internal:** allow the mock server port to be set with STAINLESS_MOCK_PORT ([1e250e9](https://github.com/prelude-so/python-sdk/commit/1e250e9c868f9b2b2840153a2c66e9e4b4cc30ad))

## 0.13.0 (2026-08-07)

Full Changelog: [v0.12.0...v0.13.0](https://github.com/prelude-so/python-sdk/compare/v0.12.0...v0.13.0)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "prelude-python-sdk"
version = "0.13.0"
version = "0.14.0"
description = "The official Python library for the Prelude API"
dynamic = ["readme"]
license = "Apache-2.0"
Expand Down
13 changes: 10 additions & 3 deletions scripts/mock
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ set -e

cd "$(dirname "$0")/.."

if [ "$1" == "--install" ]; then
npm exec --package=@stdy/cli@0.22.1 -- steady --version
exit 0
fi

if [[ -n "$1" && "$1" != '--'* ]]; then
URL="$1"
shift
Expand All @@ -20,16 +25,18 @@ fi
echo "==> Starting mock server with URL ${URL}"

# Run steady mock on the given spec
MOCK_PORT="${STAINLESS_MOCK_PORT:-4010}"

if [ "$1" == "--daemon" ]; then
# Pre-install the package so the download doesn't eat into the startup timeout
npm exec --package=@stdy/cli@0.22.1 -- steady --version

npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" &> .stdy.log &
npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p "$MOCK_PORT" --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" &> .stdy.log &

# Wait for server to come online via health endpoint (max 30s)
echo -n "Waiting for server"
attempts=0
while ! curl --silent --fail "http://127.0.0.1:4010/_x-steady/health" >/dev/null 2>&1; do
while ! curl --silent --fail "http://127.0.0.1:$MOCK_PORT/_x-steady/health" >/dev/null 2>&1; do
if ! kill -0 $! 2>/dev/null; then
echo
cat .stdy.log
Expand All @@ -48,5 +55,5 @@ if [ "$1" == "--daemon" ]; then

echo
else
npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL"
npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p "$MOCK_PORT" --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL"
fi
12 changes: 9 additions & 3 deletions scripts/test
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color

MOCK_PORT="${STAINLESS_MOCK_PORT:-4010}"

function steady_is_running() {
curl --silent "http://127.0.0.1:4010/_x-steady/health" >/dev/null 2>&1
curl --silent "http://127.0.0.1:$MOCK_PORT/_x-steady/health" >/dev/null 2>&1
}

kill_server_on_port() {
Expand All @@ -27,7 +29,7 @@ function is_overriding_api_base_url() {

if ! is_overriding_api_base_url && ! steady_is_running ; then
# When we exit this script, make sure to kill the background mock server process
trap 'kill_server_on_port 4010' EXIT
trap 'kill_server_on_port "$MOCK_PORT"' EXIT

# Start the dev server
./scripts/mock --daemon
Expand All @@ -43,7 +45,7 @@ elif ! steady_is_running ; then
echo -e "To run the server, pass in the path or url of your OpenAPI"
echo -e "spec to the steady command:"
echo
echo -e " \$ ${YELLOW}npm exec --package=@stdy/cli@0.22.1 -- steady path/to/your.openapi.yml --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets${NC}"
echo -e " \$ ${YELLOW}npm exec --package=@stdy/cli@0.22.1 -- steady path/to/your.openapi.yml --host 127.0.0.1 -p $MOCK_PORT --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets${NC}"
echo

exit 1
Expand All @@ -52,6 +54,10 @@ else
echo
fi

if [ -n "${STAINLESS_MOCK_PORT:-}" ] && ! is_overriding_api_base_url ; then
export TEST_API_BASE_URL="http://127.0.0.1:$MOCK_PORT"
fi

export DEFER_PYDANTIC_BUILD=false

echo "==> Running tests"
Expand Down
2 changes: 1 addition & 1 deletion src/prelude_python_sdk/_version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.

__title__ = "prelude_python_sdk"
__version__ = "0.13.0" # x-release-please-version
__version__ = "0.14.0" # x-release-please-version
20 changes: 20 additions & 0 deletions src/prelude_python_sdk/resources/notify.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ def get_subscription_config(
"""
Retrieve a specific subscription management configuration by its ID.

In order to get access to this endpoint, contact our support team.

Args:
extra_headers: Send extra headers

Expand Down Expand Up @@ -110,6 +112,8 @@ def get_subscription_phone_number(
Retrieve the current subscription status for a specific phone number within a
subscription configuration.

In order to get access to this endpoint, contact our support team.

Args:
extra_headers: Send extra headers

Expand Down Expand Up @@ -154,6 +158,8 @@ def list_subscription_configs(
Each configuration represents a subscription management setup with phone numbers
for receiving opt-out/opt-in requests and a callback URL for webhook events.

In order to get access to this endpoint, contact our support team.

Args:
cursor: Pagination cursor from the previous response

Expand Down Expand Up @@ -205,6 +211,8 @@ def list_subscription_phone_number_events(

Events are ordered by timestamp in descending order (most recent first).

In order to get access to this endpoint, contact our support team.

Args:
cursor: Pagination cursor from the previous response

Expand Down Expand Up @@ -264,6 +272,8 @@ def list_subscription_phone_numbers(

You can optionally filter by subscription state (SUB or UNSUB).

In order to get access to this endpoint, contact our support team.

Args:
cursor: Pagination cursor from the previous response

Expand Down Expand Up @@ -541,6 +551,8 @@ async def get_subscription_config(
"""
Retrieve a specific subscription management configuration by its ID.

In order to get access to this endpoint, contact our support team.

Args:
extra_headers: Send extra headers

Expand Down Expand Up @@ -576,6 +588,8 @@ async def get_subscription_phone_number(
Retrieve the current subscription status for a specific phone number within a
subscription configuration.

In order to get access to this endpoint, contact our support team.

Args:
extra_headers: Send extra headers

Expand Down Expand Up @@ -620,6 +634,8 @@ async def list_subscription_configs(
Each configuration represents a subscription management setup with phone numbers
for receiving opt-out/opt-in requests and a callback URL for webhook events.

In order to get access to this endpoint, contact our support team.

Args:
cursor: Pagination cursor from the previous response

Expand Down Expand Up @@ -671,6 +687,8 @@ async def list_subscription_phone_number_events(

Events are ordered by timestamp in descending order (most recent first).

In order to get access to this endpoint, contact our support team.

Args:
cursor: Pagination cursor from the previous response

Expand Down Expand Up @@ -730,6 +748,8 @@ async def list_subscription_phone_numbers(

You can optionally filter by subscription state (SUB or UNSUB).

In order to get access to this endpoint, contact our support team.

Args:
cursor: Pagination cursor from the previous response

Expand Down
9 changes: 9 additions & 0 deletions src/prelude_python_sdk/types/verification_create_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,15 @@ class Signals(TypedDict, total=False):
device_platform: Literal["android", "ios", "ipados", "tvos", "web"]
"""The type of the user's device."""

existing_user: bool
"""
Whether the end-user already exists in your system, for example an existing
account signing in again rather than a first-time signup. Unlike
`is_trusted_user`, this signal does not bypass fraud checks; it is taken into
account as one additional anti-fraud signal. For more details, refer to
[Signals](/verify/v2/documentation/prevent-fraud#signals).
"""

ip: str
"""The public IP v4 or v6 address of the end-user's device.

Expand Down
9 changes: 9 additions & 0 deletions src/prelude_python_sdk/types/watch_predict_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,15 @@ class Signals(TypedDict, total=False):
device_platform: Literal["android", "ios", "ipados", "tvos", "web"]
"""The type of the user's device."""

existing_user: bool
"""
Whether the end-user already exists in your system, for example an existing
account signing in again rather than a first-time signup. Unlike
`is_trusted_user`, this signal does not bypass fraud checks; it is taken into
account as one additional anti-fraud signal. For more details, refer to
[Signals](/verify/v2/documentation/prevent-fraud#signals).
"""

ip: str
"""The public IP v4 or v6 address of the end-user's device.

Expand Down
4 changes: 4 additions & 0 deletions src/prelude_python_sdk/types/watch_predict_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class WatchPredictResponse(BaseModel):
risk_factors: Optional[
List[
Literal[
"account_risk_profile",
"behavioral_pattern",
"device_attribute",
"fraud_database",
Expand All @@ -42,6 +43,9 @@ class WatchPredictResponse(BaseModel):
Only present when prediction is "suspicious" and the anti-fraud system detected
specific risk signals.

- `account_risk_profile` - The target matches a risk profile derived from the
outcomes reported on your own account, rather than from a signal shared across
accounts.
- `behavioral_pattern` - The phone number past behavior during verification
flows exhibits suspicious patterns.
- `device_attribute` - The device exhibits characteristics associated with
Expand Down
2 changes: 2 additions & 0 deletions tests/api_resources/test_verification.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ def test_method_create_with_all_params(self, client: Prelude) -> None:
"device_id": "8F0B8FDD-C2CB-4387-B20A-56E9B2E5A0D2",
"device_model": "iPhone17,2",
"device_platform": "ios",
"existing_user": False,
"ip": "203.0.113.123",
"is_trusted_user": False,
"ja4_fingerprint": "t13d1516h2_8daaf6152771_e5627efa2ab1",
Expand Down Expand Up @@ -208,6 +209,7 @@ async def test_method_create_with_all_params(self, async_client: AsyncPrelude) -
"device_id": "8F0B8FDD-C2CB-4387-B20A-56E9B2E5A0D2",
"device_model": "iPhone17,2",
"device_platform": "ios",
"existing_user": False,
"ip": "203.0.113.123",
"is_trusted_user": False,
"ja4_fingerprint": "t13d1516h2_8daaf6152771_e5627efa2ab1",
Expand Down
2 changes: 2 additions & 0 deletions tests/api_resources/test_watch.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ def test_method_predict_with_all_params(self, client: Prelude) -> None:
"device_id": "8F0B8FDD-C2CB-4387-B20A-56E9B2E5A0D2",
"device_model": "iPhone17,2",
"device_platform": "ios",
"existing_user": False,
"ip": "203.0.113.123",
"is_trusted_user": False,
"ja4_fingerprint": "t13d1516h2_8daaf6152771_e5627efa2ab1",
Expand Down Expand Up @@ -227,6 +228,7 @@ async def test_method_predict_with_all_params(self, async_client: AsyncPrelude)
"device_id": "8F0B8FDD-C2CB-4387-B20A-56E9B2E5A0D2",
"device_model": "iPhone17,2",
"device_platform": "ios",
"existing_user": False,
"ip": "203.0.113.123",
"is_trusted_user": False,
"ja4_fingerprint": "t13d1516h2_8daaf6152771_e5627efa2ab1",
Expand Down