The pricing-related types in src/resource_clients/actor.ts are behind both the API and the Python client. As a result, TypeScript consumers reading eventPriceUsd or pricePerUnitUsd get a non-optional number and .toFixed(...) crashes on tiered Store Actors — surfaced downstream in
apify/apify-cli#1171.
Gaps (vs apify-client-python)
| Field |
Python |
JS today |
Status |
ActorChargeEvent.eventPriceUsd |
float | None = None |
number (required) |
wrong — crashes consumers |
ActorChargeEvent.eventTieredPricingUsd |
dict[str, TieredPricingPerEventEntry] | None |
missing |
missing |
ActorChargeEvent.isPrimaryEvent / isOneTimeEvent |
bool | None |
missing |
missing |
PricePerDatasetItemActorPricingInfo.pricePerUnitUsd |
float | None = None |
number (required) |
wrong |
PricePerDatasetItemActorPricingInfo.tieredPricing |
dict[str, TieredPricingPerDatasetItemEntry] | None |
missing |
missing |
TieredPricingPerEventEntry |
dataclass |
missing |
missing |
TieredPricingPerDatasetItemEntry |
dataclass |
missing |
missing |
CommonActorPricingInfo.isPriceChangeNotificationSuppressed / forceContainsSignificantPriceChange |
bool | None |
missing |
missing |
Within both ActorChargeEvent and PricePerDatasetItemActorPricingInfo, the flat field and the tiered field are mutually exclusive (per the API docs and the Python docstring).
Proposed changes
export interface TieredPricingPerEventEntry {
tieredEventPriceUsd: number;
}
export interface TieredPricingPerDatasetItemEntry {
tieredPricePerUnitUsd: number;
}
export interface ActorChargeEvent {
eventTitle: string;
eventDescription: string;
/** Flat price per event in USD. Mutually exclusive with `eventTieredPricingUsd`. */
eventPriceUsd?: number;
/** Tier-keyed pricing. Mutually exclusive with `eventPriceUsd`. */
eventTieredPricingUsd?: Record<string, TieredPricingPerEventEntry>;
isPrimaryEvent?: boolean;
isOneTimeEvent?: boolean;
}
export interface PricePerDatasetItemActorPricingInfo extends CommonActorPricingInfo {
pricingModel: 'PRICE_PER_DATASET_ITEM';
unitName: string;
/** Flat price per unit in USD. Mutually exclusive with `tieredPricing`. */
pricePerUnitUsd?: number;
/** Tier-keyed pricing. Mutually exclusive with `pricePerUnitUsd`. */
tieredPricing?: Record<string, TieredPricingPerDatasetItemEntry>;
}
interface CommonActorPricingInfo {
apifyMarginPercentage: number;
createdAt: Date;
startedAt: Date;
notifiedAboutFutureChangeAt?: Date;
notifiedAboutChangeAt?: Date;
reasonForChange?: string;
isPriceChangeNotificationSuppressed?: boolean;
forceContainsSignificantPriceChange?: boolean;
}
Repro
# Returns a tiered PAY_PER_EVENT actor — eventPriceUsd is undefined, eventTieredPricingUsd is set.
curl https://api.apify.com/v2/acts/lukaskrivka~google-maps-with-contact-details | jq '.data.pricingInfos[-1]'
Breaking change note
Making eventPriceUsd / pricePerUnitUsd optional is technically breaking — but the current types lie about the API. Any consumer that was reading them unguarded was already crashing at runtime on tiered actors (that's #1171). Worth flagging in the changelog.
References
The pricing-related types in
src/resource_clients/actor.tsare behind both the API and the Python client. As a result, TypeScript consumers readingeventPriceUsdorpricePerUnitUsdget a non-optionalnumberand.toFixed(...)crashes on tiered Store Actors — surfaced downstream inapify/apify-cli#1171.
Gaps (vs
apify-client-python)ActorChargeEvent.eventPriceUsdfloat | None = Nonenumber(required)ActorChargeEvent.eventTieredPricingUsddict[str, TieredPricingPerEventEntry] | NoneActorChargeEvent.isPrimaryEvent/isOneTimeEventbool | NonePricePerDatasetItemActorPricingInfo.pricePerUnitUsdfloat | None = Nonenumber(required)PricePerDatasetItemActorPricingInfo.tieredPricingdict[str, TieredPricingPerDatasetItemEntry] | NoneTieredPricingPerEventEntryTieredPricingPerDatasetItemEntryCommonActorPricingInfo.isPriceChangeNotificationSuppressed/forceContainsSignificantPriceChangebool | NoneWithin both
ActorChargeEventandPricePerDatasetItemActorPricingInfo, the flat field and the tiered field are mutually exclusive (per the API docs and the Python docstring).Proposed changes
Repro
Breaking change note
Making
eventPriceUsd/pricePerUnitUsdoptional is technically breaking — but the current types lie about the API. Any consumer that was reading them unguarded was already crashing at runtime on tiered actors (that's #1171). Worth flagging in the changelog.References
apify-client-python/src/apify_client/_models.py—ActorChargeEvent,PricePerDatasetItemActorPricingInfo,TieredPricingPerEventEntry,TieredPricingPerDatasetItemEntry.apify-client-python/tests/integration/test_actor.py::test_actor_get_parses_tiered_pay_per_event.