After [deploying a token](/docs/guides/deploy-a-token), you can mint new tokens to any address and burn tokens from accounts you control. Force-burn lets admins burn from any account without the holder's signature.

These operations are available from the dashboard and the API.

## Prerequisites

- A deployed token (status: `active`)
- The `tokens:write` permission (or `tokens:admin` for force-burn)

### Allowlist tokens

For tokens with `requiresAllowlist: true` **that have an on-chain allowlist configured**, the mint endpoints auto-add a fresh destination wallet to the on-chain allowlist (and mirror it into the DB allowlist) when needed. Older allowlist tokens deployed without an on-chain list enforce the DB allowlist only — mint rejects any destination that isn't already on the list, so you must add it via `POST /allowlist` first. Both `POST /mint` and `POST /allowlist` require `tokens:write`, so any key that can mint can implicitly grow the allowlist. If you want every destination operator-approved before minting, gate `POST /mint` behind your own workflow that pre-calls `POST /allowlist` first, rather than relying on the auto-add behavior.

For tokens with an on-chain allowlist configured, operator-revoked destinations are never auto-reactivated: minting to a revoked address returns `403 DESTINATION_REVOKED` and the operator must re-add the address via `POST /allowlist` first. Legacy allowlist tokens without an on-chain list don't track a distinct revoked state — a removed destination simply fails with `403 NOT_ON_TOKEN_ALLOWLIST` until it's re-added.

## Mint tokens

### Execute mode

<Tabs items={["curl", "TypeScript", "Java"]}>
<Tab value="curl">
```bash
curl -X POST https://api.solana.com/v1/issuance/tokens/tok_abc123/mint \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: mint-001" \
  -d '{
    "mint": {
      "destination": "7xKXz...9fGh",
      "amount": "1000",
      "memo": "Initial distribution"
    }
  }'
```
</Tab>
<Tab value="TypeScript">
```typescript
const response = await fetch(
  "https://api.solana.com/v1/issuance/tokens/tok_abc123/mint",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer sk_test_...",
      "Content-Type": "application/json",
      "Idempotency-Key": "mint-001",
    },
    body: JSON.stringify({
      mint: {
        destination: "7xKXz...9fGh",
        amount: "1000",
        memo: "Initial distribution",
      },
    }),
  }
);
const { data } = await response.json();
```
</Tab>
<Tab value="Java">
```java
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.solana.com/v1/issuance/tokens/tok_abc123/mint"))
    .header("Authorization", "Bearer sk_test_...")
    .header("Content-Type", "application/json")
    .header("Idempotency-Key", "mint-001")
    .POST(HttpRequest.BodyPublishers.ofString("""
        {
          "mint": {
            "destination": "7xKXz...9fGh",
            "amount": "1000",
            "memo": "Initial distribution"
          }
        }"""))
    .build();
```
</Tab>
</Tabs>

The `amount` field is a decimal string in **UI units** (human-readable token amounts). `"1"` mints one token; `"1.5"` mints one and a half. SDP converts to on-chain base units using the token's `decimals`.

### Prepare mode

Add `/prepare` to simulate before signing:

<Tabs items={["curl", "TypeScript", "Java"]}>
<Tab value="curl">
```bash
curl -X POST https://api.solana.com/v1/issuance/tokens/tok_abc123/mint/prepare \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/json" \
  -d '{
    "mint": {
      "destination": "7xKXz...9fGh",
      "amount": "1000"
    },
    "options": { "simulate": true }
  }'
```
</Tab>
<Tab value="TypeScript">
```typescript
const response = await fetch(
  "https://api.solana.com/v1/issuance/tokens/tok_abc123/mint/prepare",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer sk_test_...",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      mint: { destination: "7xKXz...9fGh", amount: "1000" },
      options: { simulate: true },
    }),
  }
);
const { data } = await response.json();
// data.preparedTransaction.serialized — sign this
// data.simulation — { success, unitsConsumed, logs }
```
</Tab>
<Tab value="Java">
```java
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.solana.com/v1/issuance/tokens/tok_abc123/mint/prepare"))
    .header("Authorization", "Bearer sk_test_...")
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString("""
        {
          "mint": {
            "destination": "7xKXz...9fGh",
            "amount": "1000"
          },
          "options": { "simulate": true }
        }"""))
    .build();
```
</Tab>
</Tabs>

### Priority fees

Control transaction priority with `options.priorityFee`:

Values: `"none"`, `"low"`, `"medium"`, `"high"`, or a specific number in micro-lamports.

## Burn tokens

Burn tokens from an account your wallet controls:

<Tabs items={["curl", "TypeScript", "Java"]}>
<Tab value="curl">
```bash
curl -X POST https://api.solana.com/v1/issuance/tokens/tok_abc123/burn \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: burn-001" \
  -d '{
    "burn": {
      "source": "3xYZa...2aBc",
      "amount": "250",
      "memo": "Redemption"
    }
  }'
```
</Tab>
<Tab value="TypeScript">
```typescript
await fetch(
  "https://api.solana.com/v1/issuance/tokens/tok_abc123/burn",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer sk_test_...",
      "Content-Type": "application/json",
      "Idempotency-Key": "burn-001",
    },
    body: JSON.stringify({
      burn: {
        source: "3xYZa...2aBc",
        amount: "250",
        memo: "Redemption",
      },
    }),
  }
);
```
</Tab>
<Tab value="Java">
```java
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.solana.com/v1/issuance/tokens/tok_abc123/burn"))
    .header("Authorization", "Bearer sk_test_...")
    .header("Content-Type", "application/json")
    .header("Idempotency-Key", "burn-001")
    .POST(HttpRequest.BodyPublishers.ofString("""
        {
          "burn": {
            "source": "3xYZa...2aBc",
            "amount": "250",
            "memo": "Redemption"
          }
        }"""))
    .build();
```
</Tab>
</Tabs>

The `source` can be the authority wallet or its token account. Use force-burn for other holder accounts.

## Force-burn (admin)

Burn tokens from any account without the holder's signature. Requires `tokens:admin` permission:

<Tabs items={["curl", "TypeScript", "Java"]}>
<Tab value="curl">
```bash
curl -X POST https://api.solana.com/v1/issuance/tokens/tok_abc123/force-burn \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: force-burn-001" \
  -d '{
    "forceBurn": {
      "source": "3xYZa...2aBc",
      "amount": "250",
      "memo": "Compliance action"
    }
  }'
```
</Tab>
<Tab value="TypeScript">
```typescript
await fetch(
  "https://api.solana.com/v1/issuance/tokens/tok_abc123/force-burn",
  {
    method: "POST",
    headers: {
      "Authorization": "Bearer sk_test_...",
      "Content-Type": "application/json",
      "Idempotency-Key": "force-burn-001",
    },
    body: JSON.stringify({
      forceBurn: {
        source: "3xYZa...2aBc",
        amount: "250",
        memo: "Compliance action",
      },
    }),
  }
);
```
</Tab>
<Tab value="Java">
```java
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.solana.com/v1/issuance/tokens/tok_abc123/force-burn"))
    .header("Authorization", "Bearer sk_test_...")
    .header("Content-Type", "application/json")
    .header("Idempotency-Key", "force-burn-001")
    .POST(HttpRequest.BodyPublishers.ofString("""
        {
          "forceBurn": {
            "source": "3xYZa...2aBc",
            "amount": "250",
            "memo": "Compliance action"
          }
        }"""))
    .build();
```
</Tab>
</Tabs>

Both burn and force-burn also support `/prepare` endpoints for client-side signing.

## Refresh supply

After minting or burning, refresh the cached supply:

<Tabs items={["curl", "TypeScript", "Java"]}>
<Tab value="curl">
```bash
curl -X POST https://api.solana.com/v1/issuance/tokens/tok_abc123/supply/refresh \
  -H "Authorization: Bearer sk_test_..."
```
</Tab>
<Tab value="TypeScript">
```typescript
await fetch(
  "https://api.solana.com/v1/issuance/tokens/tok_abc123/supply/refresh",
  {
    method: "POST",
    headers: { "Authorization": "Bearer sk_test_..." },
  }
);
```
</Tab>
<Tab value="Java">
```java
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.solana.com/v1/issuance/tokens/tok_abc123/supply/refresh"))
    .header("Authorization", "Bearer sk_test_...")
    .POST(HttpRequest.BodyPublishers.noBody())
    .build();
```
</Tab>
</Tabs>