---
title: "Charge Endpoint"
method: POST
path: "/api/platform/charge"
tags: ["platform-sdk"]
---

# Charge Endpoint

`POST /api/platform/charge`

## Request

- Base URL: `https://api.tintin-x.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.tintin-x.com/api/platform/charge`
- Auth: none declared

Debit the user's wallet by units * meter_unit.cents.

Dual-auth — X-Internal-Key (caller identity) + body.token (subject).
Idempotent on (installation_id, idempotency_key) via DB partial
unique index.

Returns 402 on insufficient funds with a JSON body the caller can
surface to the user verbatim.

## Request body

- ChargeRequest: Body of POST /api/platform/charge. Dual-auth contract: the *caller* proves it's a legitimate app backend via X-Internal-Key; the *subject* (user being charged) is carried by the iframe JWT inside `token`. The app's user-supplied `idempotency_key` makes the call safe to retry — replays return the same charge_id without writing a new ledger row.
  - `token` string, required: iframe JWT
  - `idempotency_key` string, required
  - `unit_kind` string, required
  - `units` integer, required
  - `metadata` object, nullable

## Response `200`

Successful Response

- ChargeResponse
  - `charge_id` string, uuid, required
  - `cents_debited` integer, required
  - `wallet_balance_cents_after` integer, required
  - `idempotent_replay` boolean

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/tintin-x/apis/tintin-api.md) · [All operations](https://skmtc.dev/tintin-x/apis/tintin-api/llms.txt) · [OpenAPI document](https://skmtc.dev/tintin-x/apis/tintin-api/revisions/8839a8d0a66c?raw)
