Skip to main content

Monetization

A monetized task deducts credits from the user's balance whenever it runs. This page covers how to:

  • Enable credit charging for a task
  • Specify the amount of tool usage to charge for, including partial confirmations
  • Propagate credit charging to sub-tasks invoked via flow.executeTask() / flow.streamTask()

Monetization Configs

To enable monetization, define monetization in your config as shown below:

tasks:
- name: example-task
publish: true
monetization:
toolId: myToolId # ID used for credit tracking; contact the Monetization team to obtain one
enableSubTaskCredits: false # optional, default false — see "Sub-Task Charging" below

Tool Usage Amount

It is possible to specify the total amount of tool usage to be billed by providing usageAmount parameter in options (defaults to 1). The toolId can also be returned dynamically from options() — useful when the tool depends on the request (e.g. different models bill against different tools). A toolId returned from options() overrides the one in yaml.

@Executor("example-task")
export class ExampleExecutor implements TaskExecutor {

async options(exampleCommand: ExampleCommand): Promise<TaskOptions> {
const toolId = exampleCommand.model === 'model1' ?
'model1_tool_id' : 'default_toolId';

const totalUsageAmount = countTotalToolUsageAmount();

return {
monetization: {
toolId
},
usageAmount: totalUsageAmount,
}
}
}
usageAmount

usageAmount can be set dynamically based on your usage logic and defaults to 1 if not provided.

Ensure your project uses version 3.7.0 or higher of @picsart/pa-pluggable-workers-core to send usageAmount from options.

Partial Confirmation

When submitting results, include partialUsageAmount to indicate the exact amount of tool usage to be charged. This lets you confirm only the number of times the tool was used successfully, rather than charging for all attempts.

@Executor("example-task")
export class ExampleExecutor implements TaskExecutor {
async processTask(taskCommand: ExampleCommand): Promise<TaskResult> {
const successfulUsages = countSuccessfulGenerations();

return {
result: { exampleKey : 'exampleValue' },
meta: {
partialUsageAmount: successfulUsages,
}
};
}
}

For example, if usageAmount is set to 3 but only 2 out of 3 tool executions succeed, you can set partialUsageAmount to 2 to charge for just those successful uses. If partialUsageAmount is omitted, the full usageAmount is charged.

note

Ensure your project uses version 4.2.0 or higher of @picsart/pa-pluggable-workers-core to send meta in response.

warning

The lesser value between partialUsageAmount and usageAmount will be applied. Please ensure to send accurate values for both to avoid unexpected outcomes.

warning

If the user’s balance can’t cover the number of uses specified by usageAmount, the /submit or /execute request will fail with a 402 error.

Failure Behavior

Credits are pre-deducted and only finalized once the task completes successfully. If the task fails the deduction is rolled back automatically and the user is not charged.

Sub-Task Charging

By default, when a workflow invokes another task with flow.executeTask() or flow.streamTask(), the sub-task is not charged for credits — even if the sub-task has its own monetization.toolId configured. Set enableSubTaskCredits: true on the parent task to charge for sub-tasks it invokes (each charged using its own toolId).

tasks:
# Parent that charges itself AND its sub-tasks
- name: billable-parent
publish: true
monetization:
toolId: parent_tool_id
enableSubTaskCredits: true

# Pure orchestrator: not billed itself, but its sub-tasks are charged
- name: orchestrator-parent
publish: true
monetization:
enableSubTaskCredits: true

toolId and enableSubTaskCredits are independent. Omit toolId if the parent is just an orchestrator that shouldn't be billed itself; keep it if the parent should also charge for its own work.

Per-Call Override

Pass chargeCredits in the call options to override enableSubTaskCredits for a single call:

// Turn on credit charging for this sub-task even if enableSubTaskCredits is false
await flow.executeTask("child-task", params, { chargeCredits: true });

// Skip credit charging for this sub-task even if enableSubTaskCredits is true
const stream = flow.streamTask("child-task", params, { chargeCredits: false });
Sub-task SDK version

Sub-tasks invoked with credit management enabled must use @picsart/pa-pluggable-workers-core version 6.12.0 or higher. Calls into older sub-tasks fail fast with incompatible_sdk_version.

Deferred execution not supported

flow.defer() is not supported when sub-task credit charging is enabled. Use flow.executeTask() or flow.streamTask() instead.