Signals (Metrics)
A signal — also called a metric — is what you measure and bill on. It’s the unit of work you charge for. Examples:- A chatbot agent might have a signal called
messages(charge per message) - A document analyzer might have
pages_processed(charge per page) - An image generator might have
images_generated(charge per image) - A video service might have
minutes_transcoded(charge per minute)
Signal types: usage vs volume
Every signal has a type that controls how it’s billed:
| Type | Also known as | Bills based on | Example |
|---|---|---|---|
usage | OUTCOME | Results actually delivered | Charge per successfully analyzed document |
volume | ACTIVITY | Attempts made, successful or not | Charge per API call regardless of outcome |
usage when you want to align pricing with customer value (they only pay when they get something). Pick volume when you want to charge for the resources consumed regardless of result (they pay for every attempt because every attempt costs you money).
Most usage-based pricing for AI products uses usage. When in doubt, start there.
Create a signal
In plain English: Define a new billable metric for an agent. You do this once per metric, up front — not every time the agent works. Method & URL:name(string, max 255 chars) — Human-readable name. Shows up in reports and on invoices. Examples:"Messages Processed","Documents Analyzed","Images Generated".agentId(UUID string) — The internal ID of the agent this signal belongs to. Get it from the agent’s create response. (Note: this is the agent’sid, not itsagentCode.)
shortName(string, max 255 chars) — A machine-friendly version of the name. Used as the key in some API responses. Example:"messages","docs_analyzed". If you don’t provide one, it’s derived fromname.type("usage"|"volume", default"usage") — See the explanation above.
201 Created):
400 Bad Request— MissingnameoragentId, oragentIdisn’t a valid UUID format, ortypeisn’t"usage"or"volume".404 Not Found— TheagentIdyou provided doesn’t match any agent in this org.409 Conflict— A signal with that name or shortName already exists for this agent.
Read a signal
Method & URL:List signals
Method & URL:agentId— filter to signals for a specific agent
Update a signal
Method & URL:agentId (you can’t move a signal to a different agent — create a new one instead).
Careful with renaming. If you change a signal’s shortName after you’ve started logging usage events against it, any reports that grouped by shortName will split across the old and new names. Rename sparingly.
Delete a signal
Method & URL:Usually you don’t want to delete. For ongoing operations, prefer to just stop logging events against an old signal. Deletion is mostly for cleaning up test data or correcting mistakes during setup.
Bulk create signals
Method & URL:Using the Node SDK
Signals aren’t exposed as a separate resource in the@marginfront/sdk npm package. The SDK references signals by name (signalName) when you log usage events:
signalName MarginFront has never seen, it auto-creates a minimal signal for you — convenient for prototyping, but you’ll want to go back and set the right name and type afterwards.
How signals fit into the whole billing chain
- Customer: who’s being billed
- Agent: what’s doing the work
- Signal: what you’re measuring
- Pricing plan: how much each unit of that signal costs
- Subscription: ties a customer to a pricing plan
- Usage event: a single measurement (customer X used signal Y, quantity Z)

