Skip to main content

Pricing Strategies

A pricing strategy is the actual pricing rule inside a plan. If a pricing plan is the “Pro Plan” container, strategies are the line items: “0.01perAPIcall,""0.01 per API call," "49/month platform fee,” “5,000 calls for 99then99 then 0.03 overage.” A plan can have multiple strategies. Most plans combine a few:
  • A usage strategy for per-event billing (tied to a signal)
  • A recurring strategy for a fixed monthly fee
  • A onetime strategy for a setup fee
  • A seat_based strategy for per-user pricing
Each strategy has a charge type (what kind of charge) and a pricing model (how the math works).

Charge types

Charge typeWhat it meansExample
usagePay per event/unit. Requires a linked signal.$0.01 per API call
recurringFixed fee every billing cycle$49/month platform fee
onetimeOne-time fee, charged on first invoice only$500 setup fee
seat_basedPer-seat/per-user pricing$10/seat/month

Pricing models

The pricing model determines how the rate math works for usage and seat_based strategies.

Flat

Every unit costs the same price. Simple multiplication.
quantity × rate = total
1,000 calls × $0.01 = $10

Graduated

Different rates for different quantity ranges — like tax brackets. Each range is charged at its own rate.
Tier 1:  0–1,000    @ $0.010/call = $10.00
Tier 2:  1,001–5,000 @ $0.008/call = $32.00
Tier 3:  5,001+      @ $0.005/call = varies

1,200 calls → (1,000 × $0.01) + (200 × $0.008) = $11.60

Volume

Total quantity determines ONE rate for ALL units. The more you use, the cheaper each unit gets — but the rate applies to everything, not just the overflow.
Tier 1:  0–999     @ $0.010/call
Tier 2:  1,000–4,999 @ $0.008/call
Tier 3:  5,000+     @ $0.005/call

1,200 calls → 1,200 × $0.008 = $9.60  (all at Tier 2 rate)

Credit Pool

Flat fee for a pool of units, then per-unit overage. You pay the pool price whether you use 1 unit or all of them. Only after exceeding the pool does the overage rate kick in.
Pool:    5,000 calls for $99 flat
Overage: $0.03/call after that

3,000 calls → $99          (pool covers it)
6,000 calls → $99 + $30    (1,000 overage × $0.03)
Tier layout for credit pool:
[
  { "lower": 0, "upper": 5000, "rate": 99 },
  { "lower": 5000, "upper": null, "rate": 0.03 }
]
The first tier’s rate is the flat pool price (not per-unit). The second tier’s rate is the per-unit overage rate.

Create pricing strategies (bulk)

In plain English: Add one or more pricing strategies to a plan. You can create all your strategies in one call — send an array. Method & URL:
POST /v1/pricing-plans/{planId}/pricing-strategies
The request body is an array of strategies (even if you’re only creating one). Required fields per strategy:
  • name (string) — Strategy name, e.g. “API Call Pool”
  • agentId (UUID) — Which agent this strategy belongs to
  • chargeType (string) - One of: usage, recurring, onetime, seat_based
Optional fields:
  • signalId (UUID) — Required if chargeType is usage. The signal this strategy prices.
  • pricingModel (string) - One of: flat, graduated, volume, credit_pool. Required for usage and seat_based.
  • billingFrequency (string)monthly or yearly (default: monthly)
  • tiers (array) — Tier configuration. Each tier has lower (number), upper (number or null), rate (number).
  • rate (number) — Flat rate. Used when pricingModel is flat or there are no tiers.
  • minimumCommitment (number) — Minimum units/seats to bill for, even if actual usage is lower.
  • active (boolean, default true) — Whether this strategy is active.
  • tags (string[]) — Tags for categorization.
Example — create three strategies in one call:
curl -X POST https://api.marginfront.com/v1/pricing-plans/PLAN_ID/pricing-strategies \
  -H "x-api-key: mf_sk_test_..." \
  -H "Content-Type: application/json" \
  -d '[
    {
      "name": "API Call Pool",
      "agentId": "AGENT_ID",
      "chargeType": "usage",
      "pricingModel": "credit_pool",
      "signalId": "SIGNAL_ID",
      "tiers": [
        { "lower": 0, "upper": 5000, "rate": 99 },
        { "lower": 5000, "upper": null, "rate": 0.03 }
      ]
    },
    {
      "name": "Platform Fee",
      "agentId": "AGENT_ID",
      "chargeType": "recurring",
      "rate": 49
    },
    {
      "name": "Setup Fee",
      "agentId": "AGENT_ID",
      "chargeType": "onetime",
      "rate": 500
    }
  ]'
What you get back (201 Created): Array of created strategies with IDs. Using the SDK:
const strategies = await client.pricingStrategies.createBulk("PLAN_ID", [
  {
    name: "API Call Pool",
    agentId: "AGENT_ID",
    chargeType: "usage",
    pricingModel: "credit_pool",
    signalId: "SIGNAL_ID",
    tiers: [
      { lower: 0, upper: 5000, rate: 99 },
      { lower: 5000, upper: null, rate: 0.03 },
    ],
  },
  {
    name: "Platform Fee",
    agentId: "AGENT_ID",
    chargeType: "recurring",
    rate: 49,
  },
]);
Common errors:
  • 400 Bad Request — Missing required fields, or signalId not provided for a usage strategy.
  • 404 Not Found — Plan, agent, or signal not found in this org.

List pricing strategies

Method & URL:
GET /v1/pricing-plans/{planId}/pricing-strategies
Query parameters:
  • chargeType - Filter by charge type (usage, recurring, onetime, seat_based)
  • pricingModel — Filter by pricing model (flat, graduated, volume, credit_pool)
  • active — Filter by active status (true or false)
  • page, limit — Pagination (default: page 1, limit 10)
Using the SDK:
const { results } = await client.pricingStrategies.list("PLAN_ID", {
  chargeType: "usage",
  active: true,
});

Get a pricing strategy

Method & URL:
GET /v1/pricing-plans/{planId}/pricing-strategies/{strategyId}
Using the SDK:
const strategy = await client.pricingStrategies.get("PLAN_ID", "STRATEGY_ID");

Update a pricing strategy

Method & URL:
PATCH /v1/pricing-plans/{planId}/pricing-strategies/{strategyId}
All fields are optional. Only send what you want to change. Example — change the overage rate on a credit pool strategy:
curl -X PATCH https://api.marginfront.com/v1/pricing-plans/PLAN_ID/pricing-strategies/STRATEGY_ID \
  -H "x-api-key: mf_sk_test_..." \
  -H "Content-Type: application/json" \
  -d '{
    "tiers": [
      { "lower": 0, "upper": 5000, "rate": 99 },
      { "lower": 5000, "upper": null, "rate": 0.05 }
    ]
  }'
Using the SDK:
const updated = await client.pricingStrategies.update(
  "PLAN_ID",
  "STRATEGY_ID",
  {
    tiers: [
      { lower: 0, upper: 5000, rate: 99 },
      { lower: 5000, upper: null, rate: 0.05 },
    ],
  },
);

Bulk update + create

In plain English: Update existing strategies and create new ones in a single call. Useful when reconfiguring an entire plan. Method & URL:
PATCH /v1/pricing-plans/{planId}/pricing-strategies
Request body:
{
  "strategies": {
    "new": [
      {
        "name": "New Fee",
        "agentId": "...",
        "chargeType": "recurring",
        "rate": 29
      }
    ],
    "update": [{ "id": "EXISTING_ID", "rate": 59 }]
  }
}

Delete a pricing strategy

Method & URL:
DELETE /v1/pricing-plans/{planId}/pricing-strategies/{strategyId}
Soft-delete (sets deletedAt, doesn’t destroy data). Using the SDK:
await client.pricingStrategies.delete("PLAN_ID", "STRATEGY_ID");

How strategies fit in the billing chain

Pricing Plan ("Pro Plan")
    |
    +---- Strategy: "API Call Pool"    (usage, credit_pool)
    |       └── Signal: "api_calls"
    +---- Strategy: "Platform Fee"     (recurring, $49/mo)
    +---- Strategy: "Setup Fee"        (onetime, $500)
    +---- Strategy: "Seat License"     (seat_based, flat, $10/seat)
    |
    Subscription (assigns this plan to a customer + agent)
    |
    Invoice (sums all strategy charges for the billing period)