# Asset decimals

Source: https://docs.settlemint.com/docs/developer-guides/api-integration/asset-decimals
Understand how asset amounts work with scaled integers and dnum format.



Asset amounts in the API use **scaled integers**, not decimal numbers. This guide explains why and how to work with them correctly.

## Quick summary [#quick-summary]

* Amounts are **integers scaled by 10^decimals** (no floating-point)
* API accepts **plain strings** OR **dnum tuples** for input
* API responses return **decimal strings**: `"1.000000"` (locale-independent, trailing zeros preserve precision)
* Formula: `scaled_value = human_amount × 10^decimals`

## Why scaled integers? [#why-scaled-integers]

Computers can't do reliable decimal math. Try this in any programming language:

```
0.1 + 0.2 = 0.30000000000000004
```

For financial calculations, this is unacceptable. The solution: **store everything as integers**.

Think of it like storing money as cents instead of dollars:

* `$10.50` becomes `1050` cents
* No decimal point, no rounding errors

Blockchains use the same approach. The `decimals` field tells you how to convert:

* **0 decimals** = whole units (like shares)
* **2 decimals** = cents (like USD)
* **18 decimals** = standard for most tokens

## The dnum format [#the-dnum-format]

The platform uses **dnum** (decimal number) tuples to represent amounts:

```json
[scaled_value, decimals]
```

Examples:

* 100 shares (0 decimals): `["100", 0]`
* $10.50 (2 decimals): `["1050", 2]`
* 1.5 tokens (18 decimals): `["1500000000000000000", 18]`

The first element is a **BigInt** in code. Over JSON/HTTP, it serializes as a string to preserve precision.

## Sending API requests [#sending-api-requests]

The API accepts two formats for amounts:

### Option 1: Plain string (simpler) [#option-1-plain-string-simpler]

Just send the scaled value as a string:

```json
{
  "amounts": "1500000000000000000"
}
```

### Option 2: Dnum tuple (recommended) [#option-2-dnum-tuple-recommended]

Pairs the value with decimals—matches the response format:

```json
{
  "amounts": ["1500000000000000000", 18]
}
```

### Batch operations [#batch-operations]

For multiple amounts, use arrays:

```json
{
  "amounts": [
    ["1500000000000000000", 18],
    ["500000000000000000", 18]
  ]
}
```

## Reading API responses [#reading-api-responses]

Responses return locale-independent decimal strings. Trailing zeros encode the precision so the round-trip is lossless:

```json
{
  "totalSupply": "1000.000000000000000000",
  "basePrice": "100.00"
}
```

To convert back to human-readable, parse the decimal string directly — no division required:

```
"1000.000000000000000000" → 1000 tokens (18 decimal places of precision)
"100.00" → $100.00 (2 decimal places)
```

### Legacy format (backward compatibility) [#legacy-format-backward-compatibility]

Older API versions returned dnum tuples. Both the SDK and direct callers handle this transparently:

```json
{
  "totalSupply": ["1000000000000000000000", 18]
}
```

If you interact with a mix of old and new API versions during a rolling deployment, the deserializer accepts both formats automatically.

## Quick reference [#quick-reference]

| You want to send | Decimals | Plain string            | Dnum tuple                    |
| ---------------- | -------- | ----------------------- | ----------------------------- |
| 100 shares       | 0        | `"100"`                 | `["100", 0]`                  |
| 10.50 dollars    | 2        | `"1050"`                | `["1050", 2]`                 |
| 1.5 tokens       | 18       | `"1500000000000000000"` | `["1500000000000000000", 18]` |
| 0.001 tokens     | 18       | `"1000000000000000"`    | `["1000000000000000", 18]`    |

## Converting amounts [#converting-amounts]

### Human-readable to API format [#human-readable-to-api-format]

To convert "1.5" with 18 decimals:

```
1. Split at decimal point: whole = "1", fraction = "5"
2. Pad fraction to 18 chars: "500000000000000000"
3. Concatenate: "1" + "500000000000000000" = "1500000000000000000"
4. Result: ["1500000000000000000", 18]
```

### API response to human-readable [#api-response-to-human-readable]

Responses now return a locale-independent decimal string like `"1.500000000000000000"`. Parse the decimal point directly — no division required. The number of digits after the decimal point tells you the precision.

If you receive a legacy tuple `["1500000000000000000", 18]` (from an older server during a rolling deployment):

```
1. Divide: 1500000000000000000 ÷ 10^18 = 1 (whole part)
2. Remainder: 1500000000000000000 % 10^18 = 500000000000000000
3. Format: "1.500000000000000000"
```

<Callout type="warn" title="Use BigInt libraries">
  Never use floating-point for these calculations. Use your language's arbitrary precision integer library (BigInt,
  BigInteger, bcmath, etc.) to avoid precision loss.
</Callout>

## Checking asset decimals [#checking-asset-decimals]

![Asset detail showing contract-level decimal configuration](/docs/screenshots/bonds/bonds-detail-1.webp)

Always check the asset's decimals before sending amounts:

```bash
curl -X GET "https://your-platform.example.com/api/token/0x9459D52E60edBD3178f00F9055f6C117a21b4220" \
  -H "X-Api-Key: YOUR_API_KEY"
```

Response:

```json
{
  "name": "ACME Holdings Common Stock",
  "symbol": "ACME",
  "decimals": 0,
  "totalSupply": "1000000"
}
```

## Common mistakes [#common-mistakes]

| Mistake                      | Problem                                 | Fix                           |
| ---------------------------- | --------------------------------------- | ----------------------------- |
| `"amounts": "1.5"`           | Sends 15 smallest units, not 1.5 tokens | Multiply by 10^decimals first |
| Using `float`/`double`       | Precision loss on large numbers         | Use BigInt/BigInteger         |
| `"1.5e18"`                   | Scientific notation may not parse       | Use full integer string       |
| Forgetting to check decimals | Wrong scale for the asset               | Always GET the asset first    |

## Full example [#full-example]

```bash
# Step 1: Get asset info (including decimals)
curl -X GET "https://your-platform.example.com/api/token/0x1234..." \
  -H "X-Api-Key: YOUR_API_KEY"

# Response shows decimals: 18

# Step 2: Calculate amount for 1.5 tokens
# 1.5 × 10^18 = 1500000000000000000

# Step 3: Mint using dnum tuple (recommended)
curl -X POST "https://your-platform.example.com/api/token/0x1234.../mint" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "recipients": ["0xABCD..."],
    "amounts": ["1500000000000000000", 18],
    "walletVerification": {
      "verificationType": "PINCODE",
      "secretVerificationCode": "123456"
    }
  }'
```

## Related guides [#related-guides]

* [Mint Assets](/docs/developer-guides/asset-servicing/mint-assets) - Issue assets to investors
* [Forced Transfer](/docs/developer-guides/asset-servicing/forced-transfer) - Administrative transfers
* [API Reference](/docs/developer-guides/api-integration/api-reference) - Full OpenAPI specification
