Skip to content

Creating keys

create_private_keys mints a fresh private key inside the signer (the API service never sees plaintext) and returns the addresses derived from it. You choose the curve and which address formats to derive.

INFO

The key is generated in the isolated signer, envelope-encrypted under KMS, and stored as ciphertext. Only the derived public addresses and the privateKeyId come back.

Request

POST /public/v1/submit/create_private_keys

ParameterTypeDefaultNotes
namestring"unnamed"Human label for the key.
curvestringCURVE_SECP256K1One of CURVE_SECP256K1, CURVE_ED25519, CURVE_P256.
addressFormatsstring[]curve defaultAddress formats to derive. Omit to get the curve's default format.
environmentstring"production"Bound into the KMS encryption context.

When addressFormats is omitted, the signer derives the curve default:

CurveDefault address format
CURVE_SECP256K1ADDRESS_FORMAT_ETHEREUM
CURVE_ED25519ADDRESS_FORMAT_SOLANA
CURVE_P256ADDRESS_FORMAT_COMPRESSED

Example — SDK

ts
const { privateKeyId, addresses } = await client.createPrivateKey({
  name: "treasury-evm",
  curve: "CURVE_SECP256K1",
  addressFormats: ["ADDRESS_FORMAT_ETHEREUM"],
});

Example — raw HTTP

json
{
  "type": "ACTIVITY_TYPE_CREATE_PRIVATE_KEYS_V2",
  "timestampMs": "1748956800000",
  "organizationId": "org-…",
  "parameters": {
    "name": "treasury-evm",
    "curve": "CURVE_SECP256K1",
    "addressFormats": ["ADDRESS_FORMAT_ETHEREUM"]
  }
}

Response

result.createPrivateKeysResult holds the new key id and the derived addresses (one { format, address } entry per requested format, in request order):

json
{
  "activity": {
    "status": "ACTIVITY_STATUS_COMPLETED",
    "type": "ACTIVITY_TYPE_CREATE_PRIVATE_KEYS_V2",
    "result": {
      "createPrivateKeysResult": {
        "privateKeyIds": ["b3f1…"],
        "addresses": [
          { "format": "ADDRESS_FORMAT_ETHEREUM", "address": "0x1234…" }
        ]
      }
    }
  }
}

A bad curve fails with INVALID_CURVE; an unknown address format fails with INVALID_ADDRESS_FORMAT — both before any key is minted.

Multi-format keys

A single secp256k1 key can derive many chains at once. Request several formats and each comes back as its own entry:

json
{
  "parameters": {
    "name": "multichain",
    "curve": "CURVE_SECP256K1",
    "addressFormats": [
      "ADDRESS_FORMAT_ETHEREUM",
      "ADDRESS_FORMAT_COSMOS",
      "ADDRESS_FORMAT_BITCOIN_MAINNET_P2WPKH"
    ]
  }
}

Curve ↔ address-format compatibility

An address format is only valid for the curve whose public key it derives from. The families:

Raw public-key forms (secp256k1 / P-256)

ADDRESS_FORMAT_UNCOMPRESSED, ADDRESS_FORMAT_COMPRESSED — the raw SEC1 point, no chain encoding. COMPRESSED is the default for CURVE_P256.

secp256k1 chains

EVM, Bitcoin, Cosmos and friends derive from a secp256k1 key:

FamilyFormats
Ethereum / EVMADDRESS_FORMAT_ETHEREUM
CosmosADDRESS_FORMAT_COSMOS
SeiADDRESS_FORMAT_SEI
TronADDRESS_FORMAT_TRON
DogecoinADDRESS_FORMAT_DOGE_MAINNET, ADDRESS_FORMAT_DOGE_TESTNET
XRPADDRESS_FORMAT_XRP
SparkADDRESS_FORMAT_SPARK_MAINNET, ADDRESS_FORMAT_SPARK_REGTEST
Bitcointhe 20 variants below

Bitcoin covers every network × script-type pair — {mainnet, testnet, signet, regtest} × {P2PKH, P2SH, P2WPKH, P2WSH, P2TR}:

ADDRESS_FORMAT_BITCOIN_MAINNET_P2PKH    ADDRESS_FORMAT_BITCOIN_MAINNET_P2SH
ADDRESS_FORMAT_BITCOIN_MAINNET_P2WPKH   ADDRESS_FORMAT_BITCOIN_MAINNET_P2WSH
ADDRESS_FORMAT_BITCOIN_MAINNET_P2TR
ADDRESS_FORMAT_BITCOIN_TESTNET_P2PKH    ADDRESS_FORMAT_BITCOIN_TESTNET_P2SH
ADDRESS_FORMAT_BITCOIN_TESTNET_P2WPKH   ADDRESS_FORMAT_BITCOIN_TESTNET_P2WSH
ADDRESS_FORMAT_BITCOIN_TESTNET_P2TR
ADDRESS_FORMAT_BITCOIN_SIGNET_P2PKH     ADDRESS_FORMAT_BITCOIN_SIGNET_P2SH
ADDRESS_FORMAT_BITCOIN_SIGNET_P2WPKH    ADDRESS_FORMAT_BITCOIN_SIGNET_P2WSH
ADDRESS_FORMAT_BITCOIN_SIGNET_P2TR
ADDRESS_FORMAT_BITCOIN_REGTEST_P2PKH    ADDRESS_FORMAT_BITCOIN_REGTEST_P2SH
ADDRESS_FORMAT_BITCOIN_REGTEST_P2WPKH   ADDRESS_FORMAT_BITCOIN_REGTEST_P2WSH
ADDRESS_FORMAT_BITCOIN_REGTEST_P2TR

ed25519 chains

Solana and friends derive from an ed25519 key:

ChainFormat
SolanaADDRESS_FORMAT_SOLANA
SuiADDRESS_FORMAT_SUI
AptosADDRESS_FORMAT_APTOS
StellarADDRESS_FORMAT_XLM
TONADDRESS_FORMAT_TON_V3R2, ADDRESS_FORMAT_TON_V4R2, ADDRESS_FORMAT_TON_V5R1

See the Reference for the verbatim enum lists.

Wallets & accounts

If you prefer Turnkey's wallet/account model, create_wallet and create_wallet_accounts mint HD-style accounts (each its own key) with a per-account curve + addressFormat, up to 20 accounts per request. They reuse the same signer key-minting path as create_private_keys.

Wallet infrastructure for gasless, sponsored transactions — a Turnkey-compatible signer and a managed EIP-7702 relay.