# Account & Credits Tools

API reference for the MCP tools that report on the signed-in ZenCreator account: profile,
credit balance, and the credit-spend ledger. These tools never spend credits — they are
read-only.

There are two tools in this group:

- [`zencreator_get_me`](#zencreator_get_me) — profile + current credit balance + account flags.
- [`zencreator_list_credit_transactions`](#zencreator_list_credit_transactions) — paginated history of credit movements.

> Identity is bound to your MCP session by OAuth — there is no `user_id` argument to pass.
> Both tools always report on *you*, the authenticated user. See [Concepts](../concepts.md)
> for how the session is established.

## Standard response contract

Every tool in this group takes a `response_format` argument (`"markdown"` default, or `"json"`)
and always returns a full machine-readable `structuredContent` object in addition to the text
payload. `"markdown"` gives a human-readable summary; `"json"` returns the raw payload as text.
Clients with output-schema support get the complete `structuredContent` either way. Responses
over ~25,000 characters are truncated with a hint to paginate or switch to `response_format:"json"`.

---

## zencreator_get_me

Return the authenticated user's profile and current credit balance.

Use it to check available credits before submitting a generation, to confirm the account is
active and allowed adult content, and to read the stable `out_of_credits` flag.

**Parameters**

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `response_format` | string | No | `"markdown"` | Output format: `"markdown"` (human-readable summary) or `"json"` (raw payload as text). `structuredContent` is returned either way. |

**Returns** — `structuredContent` shape:

```json
{
  "id":             "string",
  "email":          "string | null",
  "credits":        0,
  "role":           "string",
  "is_blocked":     false,
  "nsfw_allowed":   false,
  "active":         false,
  "is_paying":      false,
  "is_trusted":     false,
  "out_of_credits": false,
  "purchase_url":   "string | null"
}
```

Field notes:

- `id` — your account UUID. Internal; do not surface it in normal replies.
- `email` — account email, or `null`.
- `credits` — current credit balance (integer).
- `role` — account role (e.g. `user`, `admin`). Internal/diagnostic.
- `is_blocked` — `true` if the account is blocked; all generations fail until lifted. Internal/diagnostic.
- `nsfw_allowed` — whether adult content is enabled on the account. **User-actionable** (see below).
- `active` — whether the account is active. Internal/diagnostic.
- `is_paying` — whether the account is a paying account. Internal/diagnostic.
- `is_trusted` — whether the account may use the trusted-only models (models marked **(trusted)** in [Models](../models.md)). Internal/diagnostic.
- `out_of_credits` — `true` when the balance is exhausted. A stable flag to branch on instead of parsing prose.
- `purchase_url` — billing link, populated **only** when `out_of_credits` is `true`; otherwise `null`.

The default surfaced answer is just **email and credits**. The fields tagged internal/diagnostic
are decision flags for the agent, not facts to read back to the user verbatim — don't print
"Role: …" / "Status: …" / "Flags: …" unless the user explicitly asks for that exact field.

`nsfw_allowed` is the exception — it is user-actionable. If `nsfw_allowed` is `false` and the
user is asking for an NSFW generation, tell them: "Adult content is disabled on your ZenCreator
account; enable it in account settings, then retry." Do not silently downgrade an NSFW request
to SFW — that hides the real reason and wastes credits. If `nsfw_allowed` is `true`, say nothing
about it. The `"markdown"` response already surfaces this warning automatically when the flag is
`false`; pass it through as-is. The markdown form likewise surfaces automatic warnings when
`out_of_credits` or `is_blocked` is `true`.

**Out of credits.** When `out_of_credits` is `true`, tell the user their balance is empty and
give them the `purchase_url` link to top up at <https://app.zencreator.pro/billing>. This is the
**same** structured signal (`out_of_credits` + `purchase_url`) that any generation tool attaches
when it fails with insufficient credits (see [The out-of-credits signal](#the-out-of-credits-signal)),
so the message reads identically whether you check ahead or hit it mid-generation. Surface it
as-is rather than rephrasing.

**Errors**

- `401` — the MCP session is no longer authorized. The user must re-authorize the server (re-run the OAuth login in their client). See [Troubleshooting](../troubleshooting.md).

**Example**

> "How many credits do I have?" — the agent calls `zencreator_get_me` and reports the `credits` field.

> Before a generation, the agent calls `zencreator_get_me` and compares `credits` against the
> price from [`zencreator_estimate_price`](../tools/generation.md) before confirming the cost with you.

---

## zencreator_list_credit_transactions

Return a paginated list of the current user's credit transactions, newest first.

Use it to audit how credits were spent, to find the cost of a specific past task, or to confirm
that a top-up was credited.

**Parameters**

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `limit` | number | No | `20` | Page size, `1`–`100`. |
| `offset` | number | No | `0` | Number of items to skip, `≥ 0`. To page, pass the previous response's `next_offset` back as `offset`. |
| `response_format` | string | No | `"markdown"` | Output format: `"markdown"` or `"json"`. `structuredContent` is returned either way. |

**Returns** — the canonical paginated envelope as `structuredContent`:

```json
{
  "total":  0,
  "count":  0,
  "offset": 0,
  "items": [
    {
      "id":               "string",
      "amount":           0,
      "resulting_amount": 0,
      "source":           "string",
      "created_at":       "string",
      "meta":             null
    }
  ],
  "has_more":    false,
  "next_offset": 0
}
```

Envelope keys:

- `total` — total number of transactions for the account.
- `count` — number of items in this page.
- `offset` — the offset this page was fetched at.
- `items` — the transactions on this page (see below).
- `has_more` — `true` if more pages remain.
- `next_offset` — offset to pass back to fetch the next page; present only when `has_more` is `true`.

Per-item fields:

- `id` — transaction UUID.
- `amount` — signed credit movement: **positive = credit added** (top-up, refund, promo), **negative = debit** (a charge for a generation).
- `resulting_amount` — the account balance immediately after this transaction.
- `source` — what produced the transaction, e.g. `task`, `call`, `stripe`, `airdrop`, `refund`.
- `created_at` — ISO 8601 timestamp.
- `meta` — free-form object or `null`. For charges it usually carries the originating `task_id` or `call_id`, which lets you map a debit back to a specific generation.

**Errors**

- `401` — the MCP session is no longer authorized. The user must re-authorize the server. See [Troubleshooting](../troubleshooting.md).

**Example**

> "Show my last 5 charges" — the agent calls with `limit=5` and reports the items where `amount` is negative.

> "Did my top-up go through?" — the agent scans recent items for a positive `amount` with `source` `stripe`.

---

## The out-of-credits signal

ZenCreator surfaces "out of credits" the same way everywhere, so it reads identically whether
you check ahead with `zencreator_get_me` or run into it mid-generation.

When a generation runs out of credits, the backend returns **HTTP 402** and the tool result
carries this structured payload:

```json
{
  "error_code":     "insufficient_credits",
  "out_of_credits": true,
  "purchase_url":   "https://app.zencreator.pro/billing",
  "message":        "You're out of ZenCreator credits. Top up at https://app.zencreator.pro/billing to keep generating."
}
```

`zencreator_get_me` exposes the same flag proactively: when the balance is exhausted it sets
`out_of_credits: true` and populates `purchase_url` with the same billing link (and `null` while
the account is in credit). Branch on `out_of_credits` rather than parsing the message text, and
when it is `true`, direct the user to top up at <https://app.zencreator.pro/billing>.

To avoid hitting a 402 at all, estimate cost first with `zencreator_estimate_price` (or shop
models with `zencreator_compare_prices`) and state the cost before submitting — see
[Generation tools](../tools/generation.md). For deeper diagnosis of credit and NSFW issues, see
[Troubleshooting](../troubleshooting.md).

## See also

- [Concepts](../concepts.md) — sessions, tasks, calls, assets, and credits.
- [Troubleshooting](../troubleshooting.md) — out of credits, NSFW disabled, re-authorization.
- [Generation tools](../tools/generation.md) — pricing, estimation, and task submission.
