diff --git a/mintlify/docs.json b/mintlify/docs.json
index 41d5b8ec..4f636a45 100644
--- a/mintlify/docs.json
+++ b/mintlify/docs.json
@@ -142,6 +142,7 @@
"pages": [
"payouts-and-b2b/depositing-funds/depositing-funds",
"payouts-and-b2b/payment-flow/send-payment",
+ "payouts-and-b2b/payment-flow/assessing-fees",
"payouts-and-b2b/payment-flow/list-transactions",
"payouts-and-b2b/payment-flow/receipts",
"payouts-and-b2b/payment-flow/reconciliation",
diff --git a/mintlify/payouts-and-b2b/payment-flow/assessing-fees.mdx b/mintlify/payouts-and-b2b/payment-flow/assessing-fees.mdx
new file mode 100644
index 00000000..2bb14d0c
--- /dev/null
+++ b/mintlify/payouts-and-b2b/payment-flow/assessing-fees.mdx
@@ -0,0 +1,391 @@
+---
+title: "Assessing Fees"
+description: "Charge your own fee on top of Grid's fees and collect it into your platform account"
+icon: "/images/icons/coins.svg"
+"og:image": "/images/og/og-payouts-b2b.png"
+---
+
+import { FeatureCard, FeatureCardGrid } from '/snippets/feature-card.mdx';
+
+Grid lets you charge your own fee on the payments your customers send. You set the
+pricing, Grid collects the fee as part of the transaction, and the proceeds are credited
+to your platform internal account.
+
+Your fee is **additive**: it sits on top of the fees Grid charges you, and the two are
+never netted against each other.
+
+
+Configuring your own fee does not change Grid's **rates** — Grid's variable rate and fixed
+fee stay exactly as contracted. It can still change the **absolute amount** Grid collects,
+because Grid's variable fee is proportional to the amount being sent. When you lock the
+receiving amount, adding your fee raises the sending amount needed to deliver it, so the
+absolute amount Grid takes rises with it.
+
+
+## What you can charge
+
+A platform fee has two components, and you can use either or both:
+
+| Component | Field | Charged as |
+| --- | --- | --- |
+| Variable | `variableFeeBps` | Basis points (1 bps = 0.01%) of the sending amount, after fixed fees are deducted |
+| Fixed | `fixedFee` | A flat amount per transaction |
+
+Both are denominated in the **sending currency** and are charged on the sending side of the
+payment — your customer bears the fee as part of the transaction rather than you being
+billed for it separately. Which side absorbs it depends on `lockedCurrencySide`: lock the
+**sending** amount and your fee comes out of what the recipient receives; lock the
+**receiving** amount and the recipient still gets that amount, so the sender pays more.
+
+Fees are configured per **fee type**, which identifies the activity being charged:
+
+- `CROSS_CURRENCY_TRANSACTION` — a transfer where the sending currency differs from the
+ receiving currency.
+
+
+**Current limits.** Platform fees are supported for a **USD** sending currency only, and
+the fixed fee must be denominated in that same sending currency — other currencies return
+`NOT_IMPLEMENTED`. `CROSS_CURRENCY_TRANSACTION` is the only fee type you can configure
+today.
+
+Both are expanding: a `RAIL` fee type (charged for use of a payment rail) and support for
+stablecoin sending currencies such as USDC are planned. Watch the
+[changelog](/changelog) for when they land rather than assuming today's limits are
+permanent.
+
+
+
+A fee can only be charged on a transaction if you hold a platform internal account in that
+transaction's **sending currency** — that account is where the fee is credited. As more
+sending currencies become chargeable, add the matching platform account before you enable a
+fee for them.
+
+
+### How the amount is calculated
+
+Every fixed fee on the transaction — yours and Grid's — is subtracted first. The variable
+rates are then applied together to what remains:
+
+```text
+total_variable_fee = (sending_amount - platform_fixed_fee - grid_fixed_fee)
+ x (platform_variable_fee + grid_variable_fee)
+```
+
+Your share of that total is your own rate's portion of it. Each component is rounded
+independently to the smallest currency unit, so your fee and Grid's are each exact.
+
+For a \$10.00 USD payment where your fee is 30 bps + \$0.50 and Grid charges 100 bps with
+no fixed fee:
+
+```text
+after fixed fees = 1000 - 50 - 0 = 950 cents
+your variable = 950 x 0.0030 = 2.85 -> 3 cents
+your fixed = 50 cents
+your platform fee = 53 cents
+```
+
+
+The variable component is charged on the sending amount **net of all fixed fees**, not on
+the gross sending amount — so Grid's fixed fee reduces the base your variable rate applies
+to, and yours reduces Grid's.
+
+
+## Configuring your fees
+
+### Standing fees
+
+Standing fees apply to every matching transaction until you change them. Set them with
+`PATCH /config`:
+
+```bash Set a standing platform fee
+curl -X PATCH 'https://api.lightspark.com/grid/2025-10-13/config' \
+ -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" \
+ -H 'Content-Type: application/json' \
+ -d '{
+ "feeConfigs": [
+ {
+ "feeType": "CROSS_CURRENCY_TRANSACTION",
+ "sourceCurrency": "USD",
+ "variableFeeBps": 30,
+ "fixedFee": {
+ "amount": 50,
+ "currency": "USD"
+ }
+ }
+ ]
+ }'
+```
+
+`feeConfigs` is a **merge-by-key upsert** keyed by `(feeType, sourceCurrency)`:
+
+- Only the keys you send are touched. Configs you omit are left unchanged.
+- Omitting `feeConfigs` entirely leaves all your fee configuration unchanged.
+- There is at most one active config per key.
+
+To read your current fees back, call `GET /config` — the response includes a `feeConfigs`
+array with every currently-active config.
+
+```bash Read current fee configuration
+curl -X GET 'https://api.lightspark.com/grid/2025-10-13/config' \
+ -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET"
+```
+
+### Turning a fee off
+
+Set both `variableFeeBps` and `fixedFee.amount` to `0` for that key. The config is
+deactivated and stops applying to new transactions:
+
+```json
+{
+ "feeConfigs": [
+ {
+ "feeType": "CROSS_CURRENCY_TRANSACTION",
+ "sourceCurrency": "USD",
+ "variableFeeBps": 0,
+ "fixedFee": { "amount": 0, "currency": "USD" }
+ }
+ ]
+}
+```
+
+### Per-transaction overrides
+
+For promotions, negotiated rates, or VIP pricing, you can override your fee on a single
+transaction by passing `platformFeeOverride` when you create the quote. The override
+**replaces** every platform fee that would otherwise have applied to that transaction —
+it is not added to your standing fee.
+
+```bash Quote with a discounted platform fee
+curl -X POST 'https://api.lightspark.com/grid/2025-10-13/quotes' \
+ -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET" \
+ -H 'Content-Type: application/json' \
+ -d '{
+ "source": {
+ "sourceType": "ACCOUNT",
+ "accountId": "InternalAccount:e85dcbd6-dced-4ec4-b756-3c3a9ea3d965"
+ },
+ "destination": {
+ "destinationType": "ACCOUNT",
+ "accountId": "ExternalAccount:a12dcbd6-dced-4ec4-b756-3c3a9ea3d123"
+ },
+ "lockedCurrencySide": "SENDING",
+ "lockedCurrencyAmount": 10000,
+ "platformFeeOverride": {
+ "platformFixedFee": {
+ "amount": 0,
+ "currency": "USD"
+ },
+ "platformVariableFeeBps": 10
+ }
+ }'
+```
+
+Both `platformFixedFee` and `platformVariableFeeBps` are **required** inside the override
+object — pass `0` for a component you want to waive. To waive your fee entirely on a
+transaction, send `0` for both.
+
+
+An override applies only to the quote it is sent on. It never changes your standing
+configuration, and it does not carry over to the next quote.
+
+
+Overrides are rejected with a `400 INVALID_INPUT` when:
+
+- The quote's sending currency is not USD.
+- `platformFixedFee.currency` does not match the quote's sending currency.
+- Either value is negative, or `platformVariableFeeBps` is above `10000` (100%).
+
+## When fees are assessed
+
+A platform fee moves through three stages:
+
+
+
+ When you create a quote, Grid resolves your fee (standing config or override) and
+ prices it into the quote. The amount is returned as `platformFeesIncluded` and is
+ locked for the lifetime of the quote.
+
+
+ Executing the quote charges the fee as part of the sending amount. Your customer pays
+ it — you are not invoiced for it separately.
+
+
+ The fee is credited to your platform internal account in the sending currency as one
+ step of the payment's settlement, not in a single moment at the end. It can land before
+ the transaction reaches `COMPLETED`.
+
+
+
+
+Because the credit happens partway through settlement, a payment that is **refunded after
+the fee has landed** reverses that credit — the fee is pulled back out of your platform
+account and returned to your customer. You will see the corresponding balance updates in
+both directions.
+
+Treat a fee as earned only once its transaction is `COMPLETED`. A fee visible in your
+balance while the payment is still in flight is not final.
+
+
+Every quote returns `platformFeesIncluded`, the portion of `feesIncluded` that you
+collect. It is `0` when no fee applies. Continuing the worked example above — a \$10.00
+send with your 30 bps + \$0.50 fee and Grid's 100 bps:
+
+```json Quote response
+{
+ "id": "Quote:019542f5-b3e7-1d02-0000-000000000006",
+ "status": "PENDING",
+ "totalSendingAmount": 1000,
+ "totalReceivingAmount": 863,
+ "exchangeRate": 0.92,
+ "feesIncluded": 63,
+ "platformFeesIncluded": 53,
+ "transactionId": "Transaction:019542f5-b3e7-1d02-0000-000000000005"
+}
+```
+
+
+`platformFeesIncluded` is **already counted inside** `feesIncluded` — do not add the two
+together. Subtract it from `feesIncluded` to get Grid's portion.
+
+
+
+Without a platform internal account in the sending currency, a payment carrying a fee fails
+rather than silently dropping the fee. See
+[Internal accounts](/payouts-and-b2b/depositing-funds/internal-accounts) to check that yours
+exists.
+
+Platform fees are also not yet supported on every payment flow. When a quote's fee cannot
+be delivered by the flow that would settle it, the quote is rejected at creation rather
+than at settlement — so you find out before your customer is charged.
+
+
+## Webhooks
+
+Platform fees do not introduce new webhook types. Two existing events carry the
+information you need:
+
+| Webhook | What it tells you |
+| --- | --- |
+| `OUTGOING_PAYMENT.*` | The transaction payload includes `platformFees` — the fee you collected on that payment. Available on every status in the lifecycle, including `COMPLETED` and `FAILED`. |
+| `INTERNAL_ACCOUNT.BALANCE_UPDATED` | Fired when your platform internal account balance changes — both when a fee is credited to it and when a refund reverses that credit back out. |
+
+To reconcile fee revenue as it accrues, listen for `OUTGOING_PAYMENT.COMPLETED` and read
+`platformFees` from the payload:
+
+```json OUTGOING_PAYMENT.COMPLETED
+{
+ "id": "Webhook:019542f5-b3e7-1d02-0000-000000000007",
+ "type": "OUTGOING_PAYMENT.COMPLETED",
+ "timestamp": "2025-08-15T14:32:00Z",
+ "data": {
+ "id": "Transaction:019542f5-b3e7-1d02-0000-000000000005",
+ "status": "COMPLETED",
+ "type": "OUTGOING",
+ "fees": 63,
+ "platformFees": 53
+ }
+}
+```
+
+
+A fee is only earned once the payment completes. A transaction that fails or is refunded
+generates no revenue — and if the fee had already been credited, the refund reverses it —
+so reconcile against terminal statuses rather than counting `platformFees` on every event
+you receive.
+
+
+See [Webhooks](/payouts-and-b2b/platform-tools/webhooks) for signature verification and
+delivery behavior.
+
+## Querying transactions and revenue
+
+### Per-transaction fees
+
+Every outgoing transaction carries `platformFees`, the portion of `fees` that you
+collected. Fetch a single transaction:
+
+```bash
+curl -X GET 'https://api.lightspark.com/grid/2025-10-13/transactions/Transaction:019542f5-b3e7-1d02-0000-000000000005' \
+ -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET"
+```
+
+Or list transactions over a date range and sum `platformFees` across the completed ones:
+
+```bash
+curl -X GET 'https://api.lightspark.com/grid/2025-10-13/transactions?status=COMPLETED&startDate=2025-10-01T00:00:00Z&endDate=2025-10-31T23:59:59Z' \
+ -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET"
+```
+
+Results are paginated — follow `nextCursor` until `hasMore` is `false` so your totals
+cover the whole period. See [List transactions](/payouts-and-b2b/payment-flow/list-transactions)
+for the full set of filters.
+
+### Accrued balance
+
+Collected fees accumulate in your platform internal account. Query its balance for the
+running total credited to you and not yet withdrawn — bearing in mind it includes fees from
+payments still in flight, which a refund can still reverse:
+
+```bash
+curl -X GET 'https://api.lightspark.com/grid/2025-10-13/platform/internal-accounts?currency=USD' \
+ -u "$GRID_CLIENT_ID:$GRID_CLIENT_SECRET"
+```
+
+
+Your platform account is a single pool, like a bank balance — fee revenue is not held in a
+separate sub-balance. If you deposit or spend from the same account, derive fee revenue by
+summing `platformFees` across transactions rather than reading the balance.
+
+
+## Testing in sandbox
+
+Platform fees work end to end in sandbox, so you can verify your pricing before going
+live. Money movements are simulated, but fees are calculated and credited exactly as they
+are in production.
+
+
+
+ Call `GET /platform/internal-accounts?currency=USD`. If no account exists, fees have
+ nowhere to land and payments carrying them will fail.
+
+
+ `PATCH /config` with a `feeConfigs` entry, then `GET /config` to confirm it is active.
+
+
+ Use `POST /sandbox/internal-accounts/{accountId}/fund` to add a test balance. See
+ [Sandbox testing](/payouts-and-b2b/platform-tools/sandbox-testing).
+
+
+ `POST /quotes` and confirm `platformFeesIncluded` matches what you expect for the
+ amount you sent. This is the fastest way to validate a fee change — no execution
+ needed.
+
+
+ Execute the quote, wait for the transaction to reach `COMPLETED`, then re-read your
+ platform account balance. It should have increased by exactly
+ `platformFeesIncluded`.
+
+
+
+
+Quote-only testing is cheap and repeatable: because the fee is priced at quote creation,
+you can sweep a range of amounts and compare `platformFeesIncluded` against your own
+pricing model without moving any money.
+
+
+To test an override, add `platformFeeOverride` to step 4 and confirm
+`platformFeesIncluded` reflects the override rather than your standing config.
+
+## Next steps
+
+
+
+ Configure currencies, webhooks, and credentials for your platform
+
+
+ Filter and paginate payment history to total your fee revenue
+
+
+ Validate your fee configuration before going live
+
+