# Create child public key

Derive and register a child key from an account-level public key.
The server derives the child extended public key using BIP-32 derivation — no cryptography
needed on the client side.

If a standalone key with the same derived value already exists in the project, it is adopted
as a child of this account key.

Only applicable to account-level keys (depth-3).

Endpoint: POST /public_keys/{public_key_id}/children
Version: 0.17.0
Security: Auth

## Path parameters:

  - `public_key_id` (string, required)
    Unique identifier (UUID) of the public key.
    Example: "550e8400-e29b-41d4-a716-446655440000"

## Request fields (application/json):

  - `change` (integer, required)
    BIP-44 change index for child key derivation.
0 = external chain (receiving addresses), 1 = internal chain (change addresses).
    Enum: 0, 1

  - `label` (string, required)
    User-friendly label for the public key

## Response 200 fields (application/json):

  - `item` (object, required)
    HD public key used to derive child addresses.

  - `item.id` (string, required)
    Unique identifier (UUID v4).

  - `item.value` (string, required)
    BIP32/SLIP-0132 extended public key in Base58Check format.

  - `item.label` (string, required)
    User-friendly label for the public key

  - `item.derivation_path` (string, required)
    HD derivation path in BIP-44 format. Supports both account-level (m/purpose'/coin_type'/account')
and change-level (m/purpose'/coin_type'/account'/change) paths.

Account-level paths (depth-3) represent HD wallet accounts and cannot derive addresses directly —
use the children endpoint to create change-level child keys first.

  - `item.children` (array)
    Child keys derived from this account-level key. Present only for account-level keys (depth-3).
Each child represents an external (change=0) or internal (change=1) chain.
    Example: [{"id":"550e8400-e29b-41d4-a716-446655440000","value":"xpub6EFxzN6ZgMCZ1PxeRigmAhm2UBGzXtZNgznCEaWuEt9efBpJwAXFA4ZckBdR1pdMQ1pBgsey7ebjToZ5gYXveftB3zwoQ8NvEkimvyaz34i","label":"Main Bitcoin Wallet","derivation_path":"m/84'/0'/0'","children":[{"id":"660e8400-e29b-41d4-a716-446655440001","value":"xpub6F7C1ZtQ411zykk6KTEoQMqfNdxiSA4uxAwAoqFanijnAavqQvVmh5zZCH6Swhdbzt2HuMRLx4chEVRZu9ic4Cnkkq5AsQcmjeMASk6FLqf","label":"external","derivation_path":"m/84'/0'/0'/0","created_at":"2025-01-15T12:00:00Z","updated_at":"2025-01-15T12:00:00Z"}],"created_at":"2025-01-15T12:00:00Z","updated_at":"2025-01-15T12:00:00Z"}]

  - `item.created_at` (string, required)
    Timestamp when the resource was created

  - `item.updated_at` (string, required)
    Timestamp when the resource was last updated

  - `references` (object, required)
    Related objects included in the response, keyed by ID.

## Response 201 fields (application/json):

  - `item` (object, required)
    HD public key used to derive child addresses.

  - `item.id` (string, required)
    Unique identifier (UUID v4).

  - `item.value` (string, required)
    BIP32/SLIP-0132 extended public key in Base58Check format.

  - `item.label` (string, required)
    User-friendly label for the public key

  - `item.derivation_path` (string, required)
    HD derivation path in BIP-44 format. Supports both account-level (m/purpose'/coin_type'/account')
and change-level (m/purpose'/coin_type'/account'/change) paths.

Account-level paths (depth-3) represent HD wallet accounts and cannot derive addresses directly —
use the children endpoint to create change-level child keys first.

  - `item.children` (array)
    Child keys derived from this account-level key. Present only for account-level keys (depth-3).
Each child represents an external (change=0) or internal (change=1) chain.
    Example: [{"id":"550e8400-e29b-41d4-a716-446655440000","value":"xpub6EFxzN6ZgMCZ1PxeRigmAhm2UBGzXtZNgznCEaWuEt9efBpJwAXFA4ZckBdR1pdMQ1pBgsey7ebjToZ5gYXveftB3zwoQ8NvEkimvyaz34i","label":"Main Bitcoin Wallet","derivation_path":"m/84'/0'/0'","children":[{"id":"660e8400-e29b-41d4-a716-446655440001","value":"xpub6F7C1ZtQ411zykk6KTEoQMqfNdxiSA4uxAwAoqFanijnAavqQvVmh5zZCH6Swhdbzt2HuMRLx4chEVRZu9ic4Cnkkq5AsQcmjeMASk6FLqf","label":"external","derivation_path":"m/84'/0'/0'/0","created_at":"2025-01-15T12:00:00Z","updated_at":"2025-01-15T12:00:00Z"}],"created_at":"2025-01-15T12:00:00Z","updated_at":"2025-01-15T12:00:00Z"}]

  - `item.created_at` (string, required)
    Timestamp when the resource was created

  - `item.updated_at` (string, required)
    Timestamp when the resource was last updated

  - `references` (object, required)
    Related objects included in the response, keyed by ID.

## Response 400 fields (application/problem+json):

  - `type` (string, required)
    A URI that identifies the error type.
Open it in a browser to read about this category of error.
    Example: "https://docs.vilna.io/apis/problems/invalid-request"

  - `title` (string, required)
    A short summary of the error type.
Use detail for information specific to this occurrence.
    Example: "Invalid Request"

  - `status` (integer, required)
    The HTTP status code for this error.
Matches the status code of the HTTP response.
    Example: 400

  - `detail` (string)
    A human-readable explanation of what went wrong in this specific case.
May be localized.
    Example: "Validation error"

  - `instance` (string)
    A URI that identifies this specific error occurrence.
Include this value when contacting support.

  - `code` (string, required)
    Application-specific error code that identifies the exact error condition.
    Example: "blockchain.name_too_long"

  - `fields` (array)
    List of invalid fields in the request

  - `fields.name` (string, required)
    The name of the invalid field
    Example: "meta"

  - `fields.reason` (string, required)
    Why this field is invalid
    Example: "Exceeded maximum data size — must not exceed 1000 characters"

## Response 404 fields (application/problem+json):

  - `type` (string, required)
    A URI that identifies the error type.
Open it in a browser to read about this category of error.
    Example: "https://docs.vilna.io/apis/problems/not-found"

  - `title` (string, required)
    A short summary of the error type.
Use detail for information specific to this occurrence.
    Example: "Not Found"

  - `status` (integer, required)
    The HTTP status code for this error.
Matches the status code of the HTTP response.
    Example: 404

  - `detail` (string)
    A human-readable explanation of what went wrong in this specific case.
May be localized.
    Example: "The requested resource was not found"

  - `instance` (string)
    A URI that identifies this specific error occurrence.
Include this value when contacting support.

  - `code` (string, required)
    Application-specific error code that identifies the exact error condition.
    Example: "blockchain.not_found"

## Response 422 fields (application/problem+json):

  - `type` (string, required)
    A URI that identifies the error type.
Open it in a browser to read about this category of error.
    Example: "https://docs.vilna.io/apis/problems/precondition-failed"

  - `title` (string, required)
    A short summary of the error type.
Use detail for information specific to this occurrence.
    Example: "Precondition Failed"

  - `status` (integer, required)
    The HTTP status code for this error.
Matches the status code of the HTTP response.
    Example: 422

  - `detail` (string)
    A human-readable explanation of what went wrong in this specific case.
May be localized.
    Example: "The request cannot be processed due to failed business rule validation"

  - `instance` (string)
    A URI that identifies this specific error occurrence.
Include this value when contacting support.

  - `code` (string, required)
    Application-specific error code that identifies the exact error condition.
    Example: "simulation.failed"

  - `fields` (array)
    List of fields that failed precondition validation

  - `fields.name` (string, required)
    The name of the field that failed validation
    Example: "status"

  - `fields.reason` (string, required)
    Why the precondition failed for this field
    Example: "Cannot transition from archived to active state"

## Response default fields (application/problem+json):

  - `type` (string, required)
    A URI that identifies the error type.
Open it in a browser to read about this category of error.

  - `title` (string, required)
    A short summary of the error type.
Use detail for information specific to this occurrence.

  - `status` (integer, required)
    The HTTP status code for this error.
Matches the status code of the HTTP response.

  - `detail` (string)
    A human-readable explanation of what went wrong in this specific case.
May be localized.

  - `instance` (string)
    A URI that identifies this specific error occurrence.
Include this value when contacting support.

  - `code` (string, required)
    Application-specific error code that identifies the exact error condition.


