For AI agents: Documentation index at https://cli.internetcomputer.org/llms.txt

Skip to content
ICP CLI
Feedback welcome! Report issues on GitHub, ask questions on the Forum, or chat with us on Discord.

Tokens and Cycles

This is a command reference for managing ICP tokens and cycles. If you’re deploying to mainnet for the first time, start with Deploying to Mainnet instead.

The Internet Computer uses two primary currencies:

CurrencyPurposeUsed For
ICPGovernance tokenTrading, staking, converting to cycles
CyclesComputational fuelRunning canisters, paying for storage and compute

Canisters consume cycles to operate on mainnet. To obtain cycles, you convert ICP tokens at the current ICP/XDR exchange rate. XDR (Special Drawing Rights) is an international reserve asset used for stable pricing. One trillion cycles (1T) costs approximately 1 XDR worth of ICP.

Amount Format

All cycle and token amounts support human-readable suffixes for convenience:

  • k or K = thousand (1,000)
  • m or M = million (1,000,000)
  • b or B = billion (1,000,000,000)
  • t or T = trillion (1,000,000,000,000)

Suffixes are case-insensitive. Examples: 1.5T, 500m, 1_234.5B, 2K

Network and Environment Flags

Understanding when to use -n (network) vs -e (environment) is essential:

FlagPurposeUsed WithExample
-n icNetwork flagToken and cycles operationsicp token balance -n ic
icp cycles mint -n ic
-e icEnvironment flagDeployment and canister operationsicp deploy -e ic
icp canister status my-canister -e ic

For canister operations:

The flag you use depends on whether you’re referencing canisters by name or by ID:

  • Canister names (like my-canister) — Must use -e <environment>

    • Environment knows about your project’s canister mappings
    • Examples: icp canister status my-canister -e ic
  • Canister IDs (like ryjl3-tyaaa-aaaaa-aaaba-cai) — Can use either -e or -n

    • Use -e when working within your project context
    • Use -n when working with arbitrary canisters on a network
    • Examples: icp canister status ryjl3-tyaaa-aaaaa-aaaba-cai -n ic
Terminal window
# ✓ Works - canister name with environment
icp canister status my-canister -e ic
icp canister top-up my-canister --amount 1T -e ic
# ✗ Fails - canister name with network (no project context)
icp canister status my-canister -n ic
# ✓ Works - canister ID with network
icp canister status ryjl3-tyaaa-aaaaa-aaaba-cai -n ic
icp canister top-up ryjl3-tyaaa-aaaaa-aaaba-cai --amount 1T -n ic
# ✓ Also works - canister ID with environment
icp canister status ryjl3-tyaaa-aaaaa-aaaba-cai -e ic

Checking Balances

Check your ICP balance:

Terminal window
# On IC mainnet
icp token balance -n ic
# On local network (for testing)
icp token balance

Check your cycles balance:

Terminal window
# On IC mainnet
icp cycles balance -n ic
# On local network
icp cycles balance

Check a canister’s cycles balance:

Terminal window
# By canister name (in your project environment)
icp canister status my-canister -e ic
# By canister ID (on any network)
icp canister status ryjl3-tyaaa-aaaaa-aaaba-cai -n ic

The output includes the canister’s cycles balance.

Converting ICP to Cycles

Convert ICP tokens to cycles for use with canisters:

Terminal window
# Convert a specific amount of ICP
icp cycles mint --icp 5 -n ic
# Or request a specific amount of cycles (ICP calculated automatically)
icp cycles mint --cycles 5T -n ic

Verify your cycles balance:

Terminal window
icp cycles balance -n ic

Transferring ICP Tokens

Send ICP tokens to another principal:

Terminal window
# The 'icp' token is used by default
icp token transfer <AMOUNT> <RECEIVER> -n ic
# Explicitly specifying 'icp' is equivalent
icp token icp transfer <AMOUNT> <RECEIVER> -n ic

Examples:

Terminal window
# Send 1 ICP
icp token transfer 1 aaaaa-aa -n ic
# Send 0.5 ICP
icp token transfer 0.5 xxxxx-xxxxx-xxxxx-xxxxx-cai -n ic
# Using human-readable amounts
icp token transfer 1.5m xxxxx-xxxxx-xxxxx-xxxxx-cai -n ic

The receiver can be a principal ID or canister ID.

Getting Account Identifiers

To get your ICP ledger account identifier (for transfers to/from exchanges or wallets that don’t support principals yet):

Terminal window
icp identity account-id

See Managing Identities for more details on account identifiers.

Working with ICRC-1 Tokens

icp-cli supports ICRC-1 tokens by specifying the token’s ledger canister ID. ICRC-1 is a fungible token standard on the Internet Computer, which means all ICRC-1 tokens work with the same commands.

To transfer ICRC-1 tokens, specify the ledger canister ID. Example with ckBTC (ledger: mxzaz-hqaaa-aaaar-qaada-cai):

Terminal window
# Check ckBTC balance
icp token mxzaz-hqaaa-aaaar-qaada-cai balance -n ic
# Transfer 0.001 ckBTC
icp token mxzaz-hqaaa-aaaar-qaada-cai transfer 0.001 xxxxx-xxxxx-xxxxx-xxxxx-cai -n ic

This works with any ICRC-1 compatible token ledger on the Internet Computer.

Finding Token Ledger IDs: You can find ledger canister IDs for various tokens on the ICP Dashboard.

Approving Token Spending (Allowances)

Beyond direct transfers, ICP and ICRC-2 compatible tokens support allowances: you authorize another principal — the spender, typically a canister — to transfer a limited amount of tokens from your account on your behalf. This is the foundation for many payment and recurring-billing flows, where a canister pulls funds only when needed (for example, an exchange platform settling a trade or a service charging per use) rather than requiring you to send tokens up front.

Allowances follow the ICRC-2 standard and work with any ICRC-2 compatible ledger, including the ICP ledger.

Granting an Allowance

Use icp token approve to authorize a spender:

Terminal window
# Approve a canister to spend up to 5 ICP on your behalf
icp token approve 5 <SPENDER> -n ic
# Approve 0.01 ckBTC (any ICRC-2 ledger, by canister id)
icp token mxzaz-hqaaa-aaaar-qaada-cai approve 0.01 <SPENDER> -n ic

<SPENDER> is the principal you are authorizing (usually a canister ID). The amount is in whole tokens and supports the same human-readable suffixes as transfers.

Approvals overwrite, they do not add. Each approve call sets the allowance to the amount you specify, replacing any previous value. Approving 5 and then 2 leaves an allowance of 2, not 7. To revoke an allowance, approve 0:

Terminal window
icp token approve 0 <SPENDER> -n ic

The allowance is granted from your account, which pays the standard ledger fee (0.0001 ICP for the ICP ledger).

Setting an Expiry

For safety, you can make an allowance expire automatically with --expires-in. It accepts a relative duration (suffixes s, m, h, d, w; a bare number is seconds), the same format used elsewhere in the CLI:

Terminal window
# Allow spending for the next 24 hours only
icp token approve 5 <SPENDER> --expires-in 24h -n ic
# Expire in 30 days
icp token approve 5 <SPENDER> --expires-in 30d -n ic

A short expiry limits your exposure if the spender is ever compromised. Without --expires-in, the allowance stays in effect until you change or revoke it.

Checking an Allowance

Use icp token allowance to see how much a spender is currently authorized to transfer:

Terminal window
# Allowance you granted to a spender
icp token allowance <SPENDER> -n ic

This is a read-only query, so you can inspect any allowance — not just your own. Use --of-principal to look up the allowance another account granted:

Terminal window
# Allowance that <OWNER> granted to <SPENDER>
icp token allowance <SPENDER> --of-principal <OWNER> -n ic

The output includes the expiry, if one was set.

Allowances with Subaccounts

Both commands accept subaccount flags, specified as hex strings just like balance and transfer:

FlagCommandMeaning
--from-subaccount <hex>approveYour subaccount the allowance is granted from (the account debited)
--subaccount <hex>allowanceThe owner subaccount that granted the allowance
--spender-subaccount <hex>bothThe spender’s subaccount
Terminal window
# Approve from your subaccount 1, to the spender's subaccount 2
icp token approve 5 <SPENDER> --from-subaccount 1 --spender-subaccount 2 -n ic
# Check that same allowance
icp token allowance <SPENDER> --subaccount 1 --spender-subaccount 2 -n ic

Transferring Cycles

Transfer cycles directly to another principal via the cycles ledger:

Terminal window
icp cycles transfer <AMOUNT> <RECEIVER> -n ic

Examples:

Terminal window
# Transfer 1 trillion cycles
icp cycles transfer 1T aaaaa-aa -n ic
# Transfer 500 million cycles
icp cycles transfer 500m xxxxx-xxxxx-xxxxx-xxxxx-cai -n ic

The receiver can be a principal ID or canister ID.

Monitoring Canister Cycles

Regularly check canister cycles to avoid running out. If a canister runs out of cycles, it will be frozen and eventually deleted along with all its code and state.

Terminal window
# Check all canisters in an environment
icp canister status -e ic
# Check specific canister by name (in your project)
icp canister status my-canister -e ic
# Check specific canister by ID (on any network)
icp canister status ryjl3-tyaaa-aaaaa-aaaba-cai -n ic

Topping Up Canisters

Add cycles to a canister to keep it running:

Terminal window
# Top up by canister name (in your project)
icp canister top-up my-canister --amount 1T -e ic
# Top up by canister ID (on any network)
icp canister top-up ryjl3-tyaaa-aaaaa-aaaba-cai --amount 1T -n ic

The --amount is specified in cycles (not ICP) and supports human-readable suffixes like 1T, 500m, etc.

Cycles Transfer vs Canister Top-Up

Understanding the difference between these two commands helps you choose the right one for your use case.

The cycles ledger is an ICP system canister that tracks cycles balances for principals, similar to how the ICP ledger tracks ICP token balances.

There are two ways to send cycles:

CommandDestinationUse Case
icp cycles transferRecipient’s cycles balanceTransfer cycles to another principal’s cycles ledger balance (similar to sending tokens)
icp canister top-upCanister’s operating balanceAdd cycles directly to a canister to pay for its compute and storage

When to use each:

  • cycles transfer: Send cycles to another person/identity through the cycles ledger, similar to how you transfer ICP tokens
  • canister top-up: Directly fund a canister to keep it running (most common for maintaining canisters)

Using Different Identities

Specify which identity to use for token operations:

Terminal window
# Check balance for a specific identity
icp token balance --identity my-other-identity -n ic
# Transfer using a specific identity
icp token transfer 1 <RECEIVER> --identity my-wallet -n ic

See Managing Identities for more details.

Subaccounts

A subaccount is a 32-byte namespace under a principal. Subaccounts let a single principal manage multiple independent balances — useful for separating funds by purpose, managing deposits from multiple users, or interacting with exchanges.

Subaccounts are specified as hex strings (up to 64 characters). Shorter values are left-padded with zeros. For example, 1 becomes a 32-byte value with 01 in the last byte.

Checking a Subaccount Balance

Terminal window
# ICP token balance for a subaccount
icp token balance --subaccount 1 -n ic
# Cycles balance for a subaccount
icp cycles balance --subaccount 1 -n ic

Transferring with Subaccounts

Send from a subaccount using --from-subaccount:

Terminal window
# Transfer ICP from a subaccount
icp token transfer 1 <RECEIVER> --from-subaccount 1 -n ic
# Transfer cycles from a subaccount
icp cycles transfer 1T <RECEIVER> --from-subaccount 1 -n ic
# Mint cycles from a specific ICP subaccount
icp cycles mint --icp 5 --from-subaccount 1 -n ic

Send to a receiver’s subaccount using --to-subaccount:

Terminal window
# Send ICP to subaccount 1 of the receiver
icp token transfer 1 rrkah-fqaaa-aaaaa-aaaaq-cai --to-subaccount 1 -n ic
# Send cycles to subaccount 1 of the receiver
icp cycles transfer 1T rrkah-fqaaa-aaaaa-aaaaq-cai --to-subaccount 1 -n ic

Alternatively, you can use the ICRC-1 account format, which embeds the subaccount directly in the address. This format appends a CRC32 checksum to the principal, followed by the subaccount hex after a . separator. For example, 2vxsx-fae-22yutvy.1 is the anonymous principal (2vxsx-fae) with checksum 22yutvy and subaccount 1.

Use icp identity account-id --of-subaccount <hex> to get both the ICP ledger account ID and the ICRC-1 account format for a subaccount, rather than constructing them manually.

Receiver Address Formats

Transfer commands accept multiple receiver formats:

FormatExampleDescription
Principalrrkah-fqaaa-aaaaa-aaaaq-caiSends to the principal’s default subaccount
ICRC-1 account2vxsx-fae-22yutvy.1Principal + CRC32 checksum + subaccount hex
ICP ledger account ID64-character hex string32-byte account identifier (used by exchanges and the NNS)

The ICRC-1 account format works for both icp token transfer and icp cycles transfer. Use icp identity account-id to obtain correctly formatted addresses. ICP ledger account IDs are only accepted by icp token transfer.

Getting Account Identifiers for Subaccounts

Terminal window
# Show account identifiers for a subaccount
icp identity account-id --of-subaccount 1
# Show the icrc1 format
icp identity account-id --of-subaccount 1 --format icrc1

You can choose to the output format as either ledger (the default) or icrc1.

Fees and Safety

Transaction Fees

All transfers incur small fees:

  • ICP transfers: 0.0001 ICP fee
  • Cycles transfers: Small fee in cycles (varies by operation)
  • ICRC-1 tokens: Fee varies by token (typically minimal)

Fees are automatically deducted from your balance when you initiate a transfer.

Safety Considerations

Transfers are irreversible. Once sent, transactions cannot be undone. To minimize risk:

  • Verify receiver addresses — Double-check the principal or canister ID before sending
  • Test with small amounts — For large transfers or new recipients, send a small test amount first
  • Confirm the target network-n ic targets IC mainnet; omitting it uses your local network

Insufficient balance: If you don’t have enough funds (including fees), the transfer will fail with an error.

Troubleshooting

“Insufficient balance”

Your account doesn’t have enough ICP or cycles. Check your balance:

Terminal window
icp token balance -n ic
icp cycles balance -n ic

“Canister out of cycles”

Top up the canister:

Terminal window
# By canister name (in your project environment)
icp canister top-up my-canister --amount 1T -e ic
# By canister ID (on any network)
icp canister top-up ryjl3-tyaaa-aaaaa-aaaba-cai --amount 1T -n ic

Transfer fails

Verify:

  • The receiver address is correct
  • You have sufficient balance (including fees)
  • You’re using the correct identity

Next Steps

Browse all documentation →