# Resolve external address from public key

Compute a blockchain address from a raw public key and create an external address. The public key is used only for address computation and is not stored. If an address with the computed value already exists, returns the existing one.

Endpoint: POST /addresses/external/resolve
Version: 1.4.1
Security: Auth

## Security:

  - `Auth` (unknown)
    apiKey in header X-Api-Key scopes: api:address:write

## Request body:

  - `application/json` (unknown)
    Create an external address from a raw public key.

## Request fields (application/json):

  - `publicKey` (string, required)
    Raw public key. Hex-encoded for secp256k1 chains (EVM, Tron, Bitcoin), base58-encoded for ed25519 chains (Solana). Compressed (33 bytes) and uncompressed (65 bytes) secp256k1 keys are both accepted. 0x prefix is optional for hex keys.
    Example: 02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5

  - `addressFormat` (string, required)
    Address format for resolving an address from a public key. Restricted subset of AddressFormat — excludes p2wsh/p2wsh-testnet (script-based formats that cannot be derived from a single public key).
    Enum: "evm", "tron", "solana", "p2pkh", "p2sh", "p2wpkh", "p2pkh-testnet", "p2sh-testnet", "p2wpkh-testnet"

  - `label` (string)
    User-friendly label for the address.
    Example: user_deposit_wallet

  - `meta` (object)
    Optional key-value pairs attached to the address for tracking user associations,
source information, or custom application data.
The combined UTF-8 size of the decoded keys and values must not exceed 4096 bytes.
    Example: {"user_id":"12345","source":"exchange","category":"trading"}

## Response 200:

  - `200` (unknown)
    Created external address.

## Response 200 fields (application/json):

  - `item` (object, required)
    Externally managed address imported for tracking, either directly or from a raw public key.
    Example: {"value":"0xCa79F73628E5D46Cc2c0F6CcD3a3F934d3cE66B7","format":"evm","label":"cold_wallet","kind":"external","tag_ids":["3fa85f64-5717-4562-b3fc-2c963f66afa6"],"meta":{"source":"binance","type":"withd…

  - `item.value` (string, required)
    Blockchain address in its native format.
**Format by network**:
- **EVM**: `0x` + 40 hex chars (normalized to [EIP-55](https://eips.ethereum.org/EIPS/eip-55) checksum on import)
- **Bitcoin**: P2PKH (1...), P2SH (3...), P2WPKH (bc1...)
- **Solana**: Base58, 32-44 chars
- **Tron**: Base58, starts with `T`
    Example: 0x8521E8b15eCEF4D4269Fded3E6694225E096959E

  - `item.format` (string, required)
    Blockchain address format that determines how the address should be interpreted and validated.
    Enum: "evm", "solana", "tron", "p2pkh", "p2sh", "p2wpkh", "p2wsh", "p2tr", "p2pkh-testnet", "p2sh-testnet", "p2wpkh-testnet", "p2wsh-testnet", "p2tr-testnet"

  - `item.label` (string)
    User-friendly label for the address.
    Example: user_deposit_wallet

  - `item.kind` (string, required)
    Enum: "external"

  - `item.meta` (object)
    Optional key-value pairs attached to the address for tracking user associations,
source information, or custom application data.
The combined UTF-8 size of the decoded keys and values must not exceed 4096 bytes.
    Example: {"user_id":"12345","source":"exchange","category":"trading"}

  - `item.tag_ids` (array, required)
    IDs of the address tags assigned to this address. The full tag for each ID is included in `references.address_tags`.

  - `item.created_at` (string, required)
    Timestamp when the resource was created.
    Example: 2024-01-15T10:30:00Z

  - `item.updated_at` (string, required)
    Timestamp when the resource was last updated.
    Example: 2024-01-15T10:30:00Z

  - `references` (object, required)
    Related objects included in the response, keyed by ID.
    Example: {"public_keys":{},"address_tags":{}}

  - `references.public_keys` (object, required)
    Map of public keys indexed by their UUID ID.

  - `references.address_tags` (object, required)
    Map of address tags indexed by their UUID ID.

## Response 201:

  - `201` (unknown)
    Created external address.

## Response 201 fields (application/json):

  - `item` (object, required)
    Externally managed address imported for tracking, either directly or from a raw public key.
    Example: {"value":"0xCa79F73628E5D46Cc2c0F6CcD3a3F934d3cE66B7","format":"evm","label":"cold_wallet","kind":"external","tag_ids":["3fa85f64-5717-4562-b3fc-2c963f66afa6"],"meta":{"source":"binance","type":"withd…

  - `item.value` (string, required)
    Blockchain address in its native format.
**Format by network**:
- **EVM**: `0x` + 40 hex chars (normalized to [EIP-55](https://eips.ethereum.org/EIPS/eip-55) checksum on import)
- **Bitcoin**: P2PKH (1...), P2SH (3...), P2WPKH (bc1...)
- **Solana**: Base58, 32-44 chars
- **Tron**: Base58, starts with `T`
    Example: 0x8521E8b15eCEF4D4269Fded3E6694225E096959E

  - `item.format` (string, required)
    Blockchain address format that determines how the address should be interpreted and validated.
    Enum: "evm", "solana", "tron", "p2pkh", "p2sh", "p2wpkh", "p2wsh", "p2tr", "p2pkh-testnet", "p2sh-testnet", "p2wpkh-testnet", "p2wsh-testnet", "p2tr-testnet"

  - `item.label` (string)
    User-friendly label for the address.
    Example: user_deposit_wallet

  - `item.kind` (string, required)
    Enum: "external"

  - `item.meta` (object)
    Optional key-value pairs attached to the address for tracking user associations,
source information, or custom application data.
The combined UTF-8 size of the decoded keys and values must not exceed 4096 bytes.
    Example: {"user_id":"12345","source":"exchange","category":"trading"}

  - `item.tag_ids` (array, required)
    IDs of the address tags assigned to this address. The full tag for each ID is included in `references.address_tags`.

  - `item.created_at` (string, required)
    Timestamp when the resource was created.
    Example: 2024-01-15T10:30:00Z

  - `item.updated_at` (string, required)
    Timestamp when the resource was last updated.
    Example: 2024-01-15T10:30:00Z

  - `references` (object, required)
    Related objects included in the response, keyed by ID.
    Example: {"public_keys":{},"address_tags":{}}

  - `references.public_keys` (object, required)
    Map of public keys indexed by their UUID ID.

  - `references.address_tags` (object, required)
    Map of address tags indexed by their UUID ID.

## Response 400:

  - `400` (unknown)
    Bad request (e.g., missing or invalid fields). Invalid text may be reported as address.label_invalid, address.meta_invalid, public_key.label_invalid, invoice.comment_invalid, invoice.metadata_invalid.

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

  - `type` (string, required)
    A URI that identifies the error type.
    Example: https://docs.vilna.io/apis/errors#internal-error

  - `title` (string, required)
    A short summary of the error type.
Use `detail` for information specific to this occurrence.
    Example: Bad 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: The address is already assigned to another invoice

  - `instance` (string)
    A URI that identifies this specific error occurrence.
Include this value when contacting support.
    Example: /traces/0123456789abcdef0123456789abcdef

  - `code` (string, required)
    Stable machine-readable error code for programmatic error handling. Unlike the HTTP `status` or free-form `detail`, this code is guaranteed not to change between versions for a given error condition, so it is safe to branch on in client code. Defaults to `unspecified` when the server has not assigned a specific code.
    Example: blockchain.not_found

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

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

  - `fields.reason` (string, required)
    Why this field is invalid.
    Example: 32

## Response 401:

  - `401` (unknown)
    Missing or invalid authentication credentials.

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

  - `type` (string, required)
    A URI that identifies the error type.
    Example: https://docs.vilna.io/apis/errors#internal-error

  - `title` (string, required)
    A short summary of the error type.
Use `detail` for information specific to this occurrence.
    Example: Bad 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: The address is already assigned to another invoice

  - `instance` (string)
    A URI that identifies this specific error occurrence.
Include this value when contacting support.
    Example: /traces/0123456789abcdef0123456789abcdef

  - `code` (string, required)
    Stable machine-readable error code for programmatic error handling. Unlike the HTTP `status` or free-form `detail`, this code is guaranteed not to change between versions for a given error condition, so it is safe to branch on in client code. Defaults to `unspecified` when the server has not assigned a specific code.
    Example: blockchain.not_found

## Response 403:

  - `403` (unknown)
    Insufficient permissions.

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

  - `type` (string, required)
    A URI that identifies the error type.
    Example: https://docs.vilna.io/apis/errors#internal-error

  - `title` (string, required)
    A short summary of the error type.
Use `detail` for information specific to this occurrence.
    Example: Bad 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: The address is already assigned to another invoice

  - `instance` (string)
    A URI that identifies this specific error occurrence.
Include this value when contacting support.
    Example: /traces/0123456789abcdef0123456789abcdef

  - `code` (string, required)
    Stable machine-readable error code for programmatic error handling. Unlike the HTTP `status` or free-form `detail`, this code is guaranteed not to change between versions for a given error condition, so it is safe to branch on in client code. Defaults to `unspecified` when the server has not assigned a specific code.
    Example: blockchain.not_found

## Response 409:

  - `409` (unknown)
    Request conflicts with the current resource state.

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

  - `type` (string, required)
    A URI that identifies the error type.
    Example: https://docs.vilna.io/apis/errors#internal-error

  - `title` (string, required)
    A short summary of the error type.
Use `detail` for information specific to this occurrence.
    Example: Bad 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: The address is already assigned to another invoice

  - `instance` (string)
    A URI that identifies this specific error occurrence.
Include this value when contacting support.
    Example: /traces/0123456789abcdef0123456789abcdef

  - `code` (string, required)
    Stable machine-readable error code for programmatic error handling. Unlike the HTTP `status` or free-form `detail`, this code is guaranteed not to change between versions for a given error condition, so it is safe to branch on in client code. Defaults to `unspecified` when the server has not assigned a specific code.
    Example: blockchain.not_found

## Response default:

  - `default` (unknown)
    Unexpected error.

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

  - `type` (string, required)
    A URI that identifies the error type.
    Example: https://docs.vilna.io/apis/errors#internal-error

  - `title` (string, required)
    A short summary of the error type.
Use `detail` for information specific to this occurrence.
    Example: Bad 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: The address is already assigned to another invoice

  - `instance` (string)
    A URI that identifies this specific error occurrence.
Include this value when contacting support.
    Example: /traces/0123456789abcdef0123456789abcdef

  - `code` (string, required)
    Stable machine-readable error code for programmatic error handling. Unlike the HTTP `status` or free-form `detail`, this code is guaranteed not to change between versions for a given error condition, so it is safe to branch on in client code. Defaults to `unspecified` when the server has not assigned a specific code.
    Example: blockchain.not_found

## Response 400 examples:

  - `The create-invoice request body contains malformed JSON` (unknown)

## Response 401 examples:

  - `The API service refused authentication` (unknown)

## Response 403 examples:

  - `The API key lacks the required permission` (unknown)

## Response 409 examples:

  - `The address already has an active invoice` (unknown)

  - `The address cannot be deleted while in use` (unknown)

