# Create invoice

Create a payment invoice for a specific address and token.
The address must belong to the current project and must not have an active invoice.

Endpoint: POST /invoices
Version: 0.23.9
Security: Auth

## Request fields (application/json):

  - `address` (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

  - `asset_gid` (string, required)
    Global asset identifier in [CAIP-19](https://chainagnostic.org/CAIPs/caip-19) format.

Format: {chain_gid}/{asset_path}

Examples:
- eip155:1/slip44:60 — ETH on Ethereum
- eip155:1/erc20:0xdAC17F958D2ee523a2206206994597C13D831ec7 — USDT on Ethereum
- eip155:56/bep20:0x55d398326f99059fF775485246999027B3197955 — USDT on BNB Smart Chain
- tron:0x2b6653dc/trc20:TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t — USDT on Tron
- eip155:137/erc20:0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174 — USDC on Polygon

  - `amount` (string, required)
    Amount in the smallest asset unit.

  - `expires_at` (string, required)
    Payment deadline. Must be in the future.
    Example: "2024-01-15T13:00:00Z"

  - `metadata` (object)
    Optional key-value pairs for storing additional information about the invoice.
    Example: {"order_id":"1234"}

## Response 200 fields (application/json):

  - `item` (object, required)
    Payment invoice. A request for crypto payment to a specific address for a specific token amount.
The invoice UUID is the access token — anyone with the UUID can view the invoice.

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

  - `item.address` (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

  - `item.asset_gid` (string, required)
    Global asset identifier in [CAIP-19](https://chainagnostic.org/CAIPs/caip-19) format.

Format: {chain_gid}/{asset_path}

Examples:
- eip155:1/slip44:60 — ETH on Ethereum
- eip155:1/erc20:0xdAC17F958D2ee523a2206206994597C13D831ec7 — USDT on Ethereum
- eip155:56/bep20:0x55d398326f99059fF775485246999027B3197955 — USDT on BNB Smart Chain
- tron:0x2b6653dc/trc20:TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t — USDT on Tron
- eip155:137/erc20:0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174 — USDC on Polygon

  - `item.amount` (string, required)
    Amount in the smallest asset unit.

  - `item.received_amount` (string, required)
    Amount in the smallest asset unit.

  - `item.status` (string, required)
    Current status of the invoice.
    Enum: "pending", "underpaid", "paid", "confirmed", "overpaid", "cancelled", "expired"

  - `item.expires_at` (string, required)
    Deadline for payment.
    Example: "2024-01-15T13:00:00Z"

  - `item.metadata` (object, required)
    Optional key-value pairs for storing additional information about the invoice.
    Example: {"order_id":"1234","customer":"john@example.com"}

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

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

  - `item.status_logs` (array, required)
    Chronological log of invoice status transitions with optional comments.
    Example: [{"status":"cancelled","comment":"Cancelled by merchant","changed_at":"2024-01-15T12:05:00Z"}]

  - `item.status_logs.status` (string, required)
    Current status of the invoice.
    Enum: "pending", "underpaid", "paid", "confirmed", "overpaid", "cancelled", "expired"

  - `item.status_logs.comment` (any, required)
    Optional comment explaining the status change (e.g. cancellation reason).
    Example: "Cancelled by merchant"

  - `item.status_logs.changed_at` (string, required)
    When the status transition occurred.
    Example: "2024-01-15T12:05:00Z"

  - `item.transactions` (array, required)
    Transactions detected on the invoice address since creation.
    Example: [{"hash":"0xabc123def456789012345678901234567890123456789012345678901234abcd","block_number":12345678,"is_success":true,"detected_at":"2024-01-15T12:05:00Z","confirmed_at":"2024-01-15T12:15:00Z","deposits":[{"asset_gid":"eip155:56/bep20:0x55d398326f99059fF775485246999027B3197955","amount":"42500000","is_matched":true}]}]

  - `item.transactions.hash` (string, required)
    Transaction hash identifier on the blockchain.
    Example: "0xabc123def456789012345678901234567890123456789012345678901234abcd"

  - `item.transactions.block_number` (integer, required)
    Block number/height on the blockchain.
    Example: 12345678

  - `item.transactions.is_success` (boolean, required)
    Whether the transaction executed successfully on-chain.
    Example: true

  - `item.transactions.detected_at` (string, required)
    When the transaction was first seen.
    Example: "2024-01-15T12:05:00Z"

  - `item.transactions.confirmed_at` (any, required)
    When the transaction reached required confirmations. Null if not yet confirmed.
    Example: "2024-01-15T12:15:00Z"

  - `item.transactions.deposits` (array, required)
    Individual token deposits received within this transaction.
    Example: [{"asset_gid":"eip155:56/bep20:0x55d398326f99059fF775485246999027B3197955","amount":"42500000","is_matched":true}]

  - `item.transactions.deposits.asset_gid` (string, required)
    Global asset identifier in [CAIP-19](https://chainagnostic.org/CAIPs/caip-19) format.

Format: {chain_gid}/{asset_path}

Examples:
- eip155:1/slip44:60 — ETH on Ethereum
- eip155:1/erc20:0xdAC17F958D2ee523a2206206994597C13D831ec7 — USDT on Ethereum
- eip155:56/bep20:0x55d398326f99059fF775485246999027B3197955 — USDT on BNB Smart Chain
- tron:0x2b6653dc/trc20:TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t — USDT on Tron
- eip155:137/erc20:0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174 — USDC on Polygon
    Example: "eip155:56/bep20:0x55d398326f99059fF775485246999027B3197955"

  - `item.transactions.deposits.amount` (string, required)
    Deposit amount in base units (smallest token denomination). Use the token metadata
from the references.tokens map to format the value for display.
If the token is not in references.tokens, it is not tracked by the project.
    Example: "42500000"

  - `item.transactions.deposits.is_matched` (boolean, required)
    Whether this deposit's token matches the invoice's expected token.
    Example: true

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

  - `references.tokens` (object, required)
    Map of tokens indexed by their CAIP-19 Asset GID.

  - `references.blockchains` (object, required)
    Map of blockchains indexed by their CAIP-2 Chain GID.

## 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)
    Stable machine-readable error code ({domain}.{reason}) 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.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 401 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/unauthorized"

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

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

  - `detail` (string)
    A human-readable explanation of what went wrong in this specific case.
May be localized.
    Example: "Missing or invalid authentication credentials"

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

  - `code` (string, required)
    Stable machine-readable error code ({domain}.{reason}) 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: "auth.unauthorized"

## Response 403 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/forbidden"

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

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

  - `detail` (string)
    A human-readable explanation of what went wrong in this specific case.
May be localized.
    Example: "You do not have permission to perform this action"

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

  - `code` (string, required)
    Stable machine-readable error code ({domain}.{reason}) 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: "chain.not_allowed"

## 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)
    Stable machine-readable error code ({domain}.{reason}) 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 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/conflict"

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

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

  - `detail` (string)
    A human-readable explanation of what went wrong in this specific case.
May be localized.
    Example: "Resource already exists with the same identifier"

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

  - `code` (string, required)
    Stable machine-readable error code ({domain}.{reason}) 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: "invoice.address_occupied"

## 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)
    Stable machine-readable error code ({domain}.{reason}) 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: "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)
    Stable machine-readable error code ({domain}.{reason}) 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.


