First signals
Prerequisites
- Have your API key ready.
- [Optional] Configure Customers and Products with external ids. Or programmatically via API endpoints: Create product, Create customer.
Sending signals
Send a signal by calling the SDK with an event name and optional attribution. Signals represent actions your agent takes; use them to drive billing, track delivered value, or both. To attach a signal to a customer’s product usage, provide both customer and product ids. Unattributed signals are still saved and visible in the dashboard.
Python
Node.js
Consuming multiple credits per signal
By default, each signal consumes the fixed credit cost defined in your product’s pricing configuration (typically 1 credit). To consume a variable number of credits per signal, you can configure your pricing rule to read a quantity value from signal data.
Pricing configuration
For quantity-based credit consumption to work, your product’s prepaid credits pricing line must have a quantity mapping configured. This tells Paid which field in the signal’s data object contains the quantity value. Configure this in the product’s pricing settings by adding a quantity property that maps to the signal data path (e.g., $.quantity).
Without this mapping, every signal consumes the fixed credit cost regardless of what you send in data.
Sending quantity in signals
Once the pricing rule is configured, pass a quantity field in the signal’s data object. This is useful when a single action should deduct more than one credit. For example, a long-running workflow that consumes 5 credits, or a batch operation where credit cost scales with the size of the work performed.
Python
Node.js
The quantity value is multiplied by the credit cost on the pricing rule. For example, if the pricing rule defines a credit cost of 1 and the signal sends quantity: 5, that signal deducts 5 credits. If the credit cost is 2 and quantity is 3, that signal deducts 6 credits.
When quantity is omitted, it defaults to 1.
User-level tracking within a customer
Signals are attributed to customers and products, but you can also track which individual user within a customer organization performed the action. Pass external_user_id in the signal’s data field, matching the external ID of a user created via the user management API.
Python
Node.js
When external_user_id is present, Paid resolves the user and their seat assignment. If the user occupies a seat with seat-scoped credit balances, the credit spend is deducted from that seat’s balance. If no seat is found, credits are deducted from the organization pool as usual.
The data object is stored exactly as you send it, and the analytics API
queries fields by their literal key names. Use consistent keys across all SDKs
and services so that queries return complete results. The examples above use
snake_case keys in both Python and Node.js for this reason.
All fields in the data object are also queryable through the analytics API, so you can break down credit consumption by user, team, department, or any other dimension you include in signal data.