Skip to content
Switch branches/tags
Go to file
Cannot retrieve contributors at this time
150 lines (85 sloc) 6.56 KB
  CIP: 2
  Title: Counterparty Payment URI Scheme
  Author: Devon Weller 
  Status: Accepted
  Type: Informational
  Created: 2015-11-04

This CIP is based off of Bitcoin BIP 21 by Nils Schneider and Matt Corallo. This proposal extends BIP 21 to support specifying Counterparty assets.


This CIP proposes a URI scheme for making payments with Counterparty assets and Bitcoin.


The purpose of this URI scheme is to enable users to easily make payments by simply clicking links on webpages or scanning QR Codes.


Bitcoin BIP 21 is a widely used payment URI scheme for bitcoin wallets. Counterparty should follow this same best practice and modify while extending the protocol to support specifying asset names.


General rules for handling (important!)

Counterparty clients MUST NOT act on URIs without getting the user's authorization. They SHOULD require the user to manually approve each payment individually, though in some cases they MAY allow the user to automatically make this decision.

Operating system integration

Graphical Counterparty clients SHOULD register themselves as the handler for the "counterparty:" URI scheme by default, if no other handler is already registered. If there is already a registered handler, they MAY prompt the user to change it once when they first run the client.

General Format

Counterparty URIs follow the general format for URIs as set forth in RFC 3986. The path component consists of a bitcoin address, and the query component provides additional payment options.

Elements of the query component may contain characters outside the valid range. These must first be encoded according to UTF-8, and then each octet of the corresponding UTF-8 sequence must be percent-encoded as described in RFC 3986.

ABNF grammar

(See also a simpler representation of syntax)

counterpartyurn = "counterparty:" bitcoinaddress [ "?" bitcoinparams ]
bitcoinaddress  = *base58
bitcoinparams   = bitcoinparam [ "&" bitcoinparams ]
bitcoinparam    = [ amountparam / assetparam / labelparam / messageparam / otherparam / reqparam ]
amountparam     = "amount=" *digit [ "." *digit ]
assetparam      = "asset=" *assetname
labelparam      = "label=" *qchar
messageparam    = "message=" *qchar
otherparam      = qchar *qchar [ "=" *qchar ]
reqparam        = "req-" qchar *qchar [ "=" *qchar ]

Here, "qchar" corresponds to valid characters of an RFC 3986 URI query component, excluding the "=" and "&" characters, which this CIP takes as separators.

Here, "assetname" corresponds to a valid Counterparty asset name. See Transfer asset.

The scheme component ("counterparty:") is case-insensitive, and implementations must accept any combination of uppercase and lowercase letters. The rest of the URI is case-sensitive, including the query parameter keys.

Query keys

  • bitcoinaddress: A bitcoin address
  • amountparam: amount of asset to send see below
  • assetparam: the type of asset to send see below
  • label: Label for that address (e.g. name of receiver)
  • message: message that describes the transaction to the user (see examples below)
  • (others): optional, for future extensions

Transfer amount/size

If an amount is provided, it MUST be specified in decimal form and not in satoshis. All amounts MUST contain no commas and use a period (.) as the separating character to separate whole numbers and decimal fractions. e.g. amount=50.00 or amount=50 is treated as 50. amount=50,000.00 is invalid.

Counterparty clients MAY display the amount in any format that is not intended to deceive the user. They SHOULD choose a format that is foremost least confusing, and only after that most reasonable given the amount requested. For example, so long as the majority of users work in BTC units, values should always be displayed in BTC by default, even if mBTC or TBC would otherwise be a more logical interpretation of the amount.

Transfer asset

Valid Counterparty asset names are strings of 4 to 12 uppercase Latin characters (inclusive) not beginning with 'A', or integers between 26^12 + 1 and 256^8 (inclusive), prefixed with 'A'. BTC and XCP are also valid Counterparty assets.

If the URI does not specify an asset, the Counterparty client SHOULD prompt the user to specify the asset they wish to send.

Forward compatibility

Variables which are prefixed with a req- are considered required. If a client does not implement any variables which are prefixed with req-, it MUST consider the entire URI invalid. Any other variables which are not implemented, but which are not prefixed with a req-, can be safely ignored.


Simpler syntax

This section is non-normative and does not cover all possible syntax. Please see the BNF grammar above for the normative syntax.

[foo] means optional, <bar> are placeholders



Just the address:


Address with name:


Request payment of 1.3 BTC to "Devon":


Request payment of 20 SOUP to "Devon":


Request 5 XCP with a message:


Some future version that has variables which are (currently) not understood and required and thus invalid:


Some future version that has variables which are (currently) not understood but not required and thus valid:


Characters must be URI encoded properly.


This document is placed in the public domain.


Bitcoin BIP 21 by Nils Schneider and Matt Corallo