Scrawn LogoScrawn Docs
SDK ReferenceReference & Guides

Pricing DSL

Type-safe pricing expressions with mul, add, tag, inputTokens, and more

Scrawn includes a type-safe domain-specific language for expressing pricing logic. Use it inline wherever a debit or Debit value is accepted.

Functions

tag(name) Events & AI

Reference a price tag managed on the backend.

import { tag } from "@scrawn/core";

tag("PREMIUM_CALL");   // Resolved to cent amount by backend
tag("EXTRA_FEE");

amount(cents) Events & AI

Explicit cent amount as an expression node (useful inside compound expressions).

import { amount } from "@scrawn/core";

amount(500);  // $5.00

mul(...args) Events & AI

Multiply two or more values.

import { mul, tag } from "@scrawn/core";

mul(tag("PER_TOKEN"), 100);
mul(tag("BASE_RATE"), 2, tag("MULTIPLIER"));

add(...args) Events & AI

Add two or more values.

import { add, tag, amount } from "@scrawn/core";

add(tag("PREMIUM_CALL"), tag("EXTRA_FEE"));
add(tag("BASE"), 250, amount(100));

sub(...args) Events & AI

Subtract values.

import { sub, tag } from "@scrawn/core";

sub(tag("GROSS"), tag("DISCOUNT"));

div(...args) Events & AI

Integer division.

import { div, tag } from "@scrawn/core";

div(tag("TOTAL"), 2);

inputTokens() AI only

outputTokens() AI only

Token count placeholders that resolve to the actual token count of the current AI call. Only valid inside AITokenUsagePayload objects.

import { mul, tag, inputTokens, outputTokens } from "@scrawn/core";

mul(biller.tag("GPT_INPUT_RATE"), inputTokens());
mul(biller.tag("GPT_OUTPUT_RATE"), outputTokens());

Usage in Events

Pass a pricing expression where a debit value is accepted:

import { scrawn, mul, tag } from "@scrawn/core";

const biller = scrawn({
  apiKey: process.env.SCRAWN_KEY,
  baseURL: process.env.SCRAWN_BASE_URL,
});

// Tag reference
await biller.basicUsageEventConsumer({
  userId: "user-123",
  debit: tag("PREMIUM_CALL"),
});

// Compound expression
await biller.basicUsageEventConsumer({
  userId: "user-123",
  debit: mul(tag("PER_CALL"), 3),
});

For AI token billing, use inputTokens() and outputTokens() as placeholders:

async function* generateUsage() {
  yield {
    userId: "user-123",
    model: "gpt-4",
    inputTokens: 100,
    outputTokens: 50,
    inputDebit: mul(biller.tag("GPT_INPUT_RATE"), inputTokens()),
    outputDebit: mul(biller.tag("GPT_OUTPUT_RATE"), outputTokens()),
  };
}

await biller.aiTokenStreamConsumer(generateUsage());

Persisted Expressions

Store complex expressions on the backend and reference them by name:

// Reference a saved expression
await biller.basicUsageEventConsumer({
  userId: "user-123",
  debit: biller.expr("MY_PRICING_EXPR"),
});

Error Handling

Invalid expressions (wrong types, missing operands, etc.) throw PricingExpressionError at runtime. The TypeScript types catch most issues at compile time.