URI scheme | Algorand Developer Portal

URI scheme

Abstract

This ARC defines a unified Algorand URI scheme that covers payment transactions, key registration, application NoOp calls, and read-only blockchain queries. It expands on earlier URI specifications to support deeplinks, QR codes, and other contexts where structured URIs communicate transaction intent or state queries.

Motivation

This ARC consolidates and supersedes ARC-26, ARC-78, ARC-79, and ARC-82. Unifying their technical details avoids divergence across implementations, ensures extensions share consistent encoding rules, and provides a single reference for wallet, application, and tooling authors.

Specification

The key words “ MUST”, “ MUST NOT”, “ REQUIRED”, “ SHALL”, “ SHALL NOT”, “ SHOULD”, “ SHOULD NOT”, “ RECOMMENDED”, “ MAY”, and “ OPTIONAL” in this document are to be interpreted as described in RFC-2119.

Algorand URIs follow the general format for URIs as set forth in RFC 3986. The path component consists of an Algorand address, and the query component provides additional parameters specific to the encoded intent.

ABNF Overview

The productions below consolidate the syntax for all Algorand URI variants. Scheme-specific sections reference these shared rules when describing their parameters.

; Core

algorandaddress   = *base32

appid             = *digit

assetid           = *digit

; qchar corresponds to RFC 3986 query characters excluding "=" and "&"

; qbase64url matches the unpadded base64url alphabet from RFC 4648 section 5

qbase64url        = 1*(ALPHA / DIGIT / "-" / "_")

alabel            = 1*(ALPHA / DIGIT / "-" / "_" / ".")

noteparam         = "note=" *qchar

xnote             = "xnote=" *qchar

feeparam          = "fee=" *digit

otherparam        = qchar *qchar [ "=" *qchar ]

; Network authority selectors

netauth           = ghlabel / netlabel

ghlabel           = "gh:" 1*qbase64url

netlabel          = "net:" ( "testnet" / "betanet" / alabel )

; Payment transactions (ARC-26)

paymenturn        = "algorand://" [ netauth "/" ] algorandaddress [ "?" paymentparams ]

paymentparams     = paymentparam *( "&" paymentparam )

paymentparam      = amountparam / labelparam / noteparam / xnote / assetparam / otherparam

amountparam       = "amount=" *digit

labelparam        = "label=" *qchar

assetparam        = "asset=" *digit

; Key registration transactions (ARC-78)

keyregurn         = "algorand://" [ netauth "/" ] algorandaddress [ "?" keyregparams ]

keyregparams      = keyregparam *( "&" keyregparam )

keyregparam       = typekeyreg / votekeyparam / selkeyparam / sprfkeyparam / votefstparam / votelstparam / votekdparam / noteparam / xnote / feeparam / otherparam

typekeyreg        = "type=keyreg"

votekeyparam      = "votekey=" *qbase64url

selkeyparam       = "selkey=" *qbase64url

sprfkeyparam      = "sprfkey=" *qbase64url

votefstparam      = "votefst=" *digit

votelstparam      = "votelst=" *digit

votekdparam       = "votekdkey=" *digit

; Application NoOp call transactions (ARC-79)

noopurn           = "algorand://" [ netauth "/" ] algorandaddress [ "?" noopparams ]

noopparams        = noopparam *( "&" noopparam )

noopparam         = typeappl / appparam / methodparam / argparam / boxparam / assetparam / accountparam / feeparam / noteparam / xnote / otherparam

typeappl          = "type=appl"

appparam          = "app=" *digit

methodparam       = "method=" *qchar

argparam          = "arg=" *qchar

boxparam          = "box=" *qbase64url

accountparam      = "account=" *base32

; Application state queries (ARC-82 application mode)

appqueryurn       = "algorand://" [ netauth "/" ] "app/" appid [ "?" appqueryparams ]

appqueryparams    = appqueryparam *( "&" appqueryparam )

appqueryparam     = boxparam / globalparam / localparam / algaddrparam / tealcodeparam / otherparam

globalparam       = "global=" *qbase64url

localparam        = "local=" *qbase64url

algaddrparam      = "algorandaddress=" *base32

tealcodeparam     = "tealcode"

; Asset metadata queries (ARC-82 asset mode)

assetqueryurn     = "algorand://" [ netauth "/" ] "asset/" assetid [ "?" assetqueryparams ]

assetqueryparams  = assetqueryparam *( "&" assetqueryparam )

assetqueryparam   = totalparam / decimalsparam / frozenparam / unitnameparam / assetnameparam / urlparam / metadatahashparam / managerparam / reserveparam / freezeparam / clawbackparam / otherparam

totalparam        = "total"

decimalsparam     = "decimals"

frozenparam       = "frozen"

unitnameparam     = "unitname"

assetnameparam    = "assetname"

urlparam          = "url"

metadatahashparam = "metadatahash"

managerparam      = "manager"

reserveparam      = "reserve"

freezeparam       = "freeze"

clawbackparam     = "clawback"

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.

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

The scheme component (“algorand:”) 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.

Encoding Rules for qchar Values

Parameters containing text or binary data (e.g. note) MUST be encoded according to RFC 3986. Characters outside the unreserved URI set — including „=“, „&“, „%“, and any non-ASCII or binary bytes — MUST first be UTF-8 encoded and then percent-encoded (%XX format).

Implementations MUST NOT treat raw „=“ or „&“ inside values as literal characters, since these delimit query parameters.

note=foo%3Dbar%26baz           ; represents "foo=bar&baz"

note=%00%FF%AA                 ; arbitrary binary bytes (hex 00 FF AA)

note=Donation%20for%20Event   ; spaces encoded as %20

Common URI Format

Network Selection via Authority

All Algorand URI variants encode the target network in the authority component instead of relying on query parameters. The authority, when present, MUST use one of the following prefixes:

When the authority is absent (i.e., algorand:// is followed immediately by the resource path), clients MUST assume the canonical Algorand network implied by legacy authority-free URIs. For avoidance of doubt, the canonical network corresponds to Algorand MainNet. To preserve backward compatibility, emitters targeting that canonical network MUST omit the authority entirely. This rearrangement moves app and asset identifiers out of the authority and into the leading path segment, so resolvers that previously looked for those tokens in the authority MUST be updated.

Because authority-free URIs remain unchanged, applications that exclusively target the canonical network continue to generate and parse the exact same strings. Only resolvers and emitters that work with alternative networks need to adopt the gh: or net: authorities introduced here.

Client Resolution Algorithm

Network Selection Examples

Implicit default network:

algorand://asset/31566704?total

TestNet authoritative hash:

algorand://gh:<testnet_gh_b64url>/app/421337?local=bG9j

Private network alias:

algorand://net:myco-devnet/asset/31566704?total

Conflict example (invalid alias):

algorand://net:unknown-net/asset/31566704?total

Migration & Compatibility

Trade-offs

Compliance Fragment

Implementations that emit Algorand URIs and need to declare conformance with multiple ARC MUST encode that declaration in the URI fragment using the pattern #arc<A>+<B>+<C>..., where every letter represents an unpadded decimal ARC number listed in strictly ascending order. Only the first entry MAY carry the arc literal; subsequent entries MUST be bare numbers separated by + and no other separators or padding are allowed. For example, #arc26+27 is valid, while #arc26+arc27, #arc026+27, and #arc27+26 are invalid.

As a special case, declarations that include ARC-3 MUST list ARC-3 as the sole entry, using the fragment #arc3 without any additional ARC identifiers.

Consumers of this scheme SHOULD treat fragments that do not follow this structure as non-compliant and ignore the multi-ARC declaration they attempt to convey.

Example — Declaring Multi-ARC Compliance

Implementations MAY use the URI fragment to indicate which ARC standards the resource conforms to.

The following illustration uses two hypothetical future ARCs. A resource that conforms to hypothetical ARC-X and ARC-Y could expose a URI such as:

algorand://app/123456?box=AAAAAAAAAAAAA#arcX+Y

In this case, the fragment value arcX+Y declares that the asset metadata conforms to both hypothetical ARC-X and ARC-Y, where X and Y are ARC numbers.

Clients interpreting this fragment SHOULD:

  1. Strip the #arc prefix and split the remainder by the "+" separator.

Example: "arcX+Y" → [X, Y] 2. Treat the resulting list as the set of supported ARC identifiers. 3. Optionally fetch or reference the corresponding ARC specification documents,

  1. Preserve order if present, though ARC numbers SHOULD be listed in ascending order for canonical form.

Clients MUST accept any order.

Implementations MAY use the following regular expression to validate fragment values while enforcing the no-leading-zero requirement and forbidding duplicate #arc prefixes:

^(?!.*#arc.*#arc).*#arc(?!0\d)\d+(?:\+(?!0\d)\d+)*$

This mechanism ensures that multiple ARC declarations in a URI fragment can be parsed, validated, and cross-referenced unambiguously.

Transaction URIs

The base payment URI encoding provides a standardized way for applications and websites to express payment intent through deeplinks, QR codes, and similar transports. It is heavily based on Bitcoin’s BIP-0021 so existing tooling can adapt with minimal changes. The optional URI authority selects the network (gh:<hash> or net:<alias>); when omitted, clients assume the canonical network.

The ABNF overview defines paymenturn, paymentparams, and paymentparam, which extend the shared productions with the payment-specific keys described below.

Query Keys

Transfer Amount and Size

!!! Note This is DIFFERENT than Bitcoin’s BIP-0021

If an amount is provided, it MUST be specified in basic unit of the asset. For example, if it’s Algos (Algorand native unit), the amount MUST be specified in microAlgos. All amounts MUST NOT contain commas nor a period (.) - strictly non-negative integers.

For 100 Algos, the amount needs to be 100000000. For 54.1354 Algos the amount needs to be 54135400.

Algorand clients SHOULD display the amount in whole Algos. Where needed, microAlgos MAY be used as well. In any case, the units SHALL be clear for the user.

Examples

Address:

algorand://TMTAD6N22HCS2LKH7677L2KFLT3PAQWY6M4JFQFXQS32ECBFC23F57RYX4

Address with label:

algorand://TMTAD6N22HCS2LKH7677L2KFLT3PAQWY6M4JFQFXQS32ECBFC23F57RYX4?label=Silvio

Request 150.5 Algos from an address:

algorand://TMTAD6N22HCS2LKH7677L2KFLT3PAQWY6M4JFQFXQS32ECBFC23F57RYX4?amount=150500000

Request 150 units of Asset ID 45 from an address:

algorand://TMTAD6N22HCS2LKH7677L2KFLT3PAQWY6M4JFQFXQS32ECBFC23F57RYX4?amount=150&asset=45

Key Registration Transaction URIs

This extension to the base Algorand URI scheme defines how to encode key registration transactions so they can be shared through deeplinks, QR codes, and similar mechanisms while remaining compatible with the payment format introduced in ARC-26. Network selection uses the same authority-based mechanism described in the common format section.

The ABNF overview defines keyregurn, keyregparams, and keyregparam, which extend the shared productions with the key registration-specific keys enumerated below.

Scope

This section explicitly supports the two major subtypes of key registration transactions:

The following variants of keyreg transactions are not defined:

Query Keys

Examples

Encoding keyreg online transaction with minimum fee:

{
  "txn": {
    "fee": 1000,
    "fv": 1345,
    "gh:b64": "kUt08LxeVAAGHnh4JoAoAMM9ql/hBwSoiFtlnKNeOxA=",
    "lv": 2345,
    "selkey:b64": "+lfw+Y04lTnllJfncgMjXuAePe8i8YyVeoR9c1Xi78c=",
    "snd:b64": "+gJAXOr2rkSCdPQ5DEBDLjn+iIptzLxB3oSMJdWMVyQ=",
    "sprfkey:b64": "3NoXc2sEWlvQZ7XIrwVJjgjM30ndhvwGgcqwKugk1u5W/iy/JITXrykuy0hUvAxbVv0njOgBPtGFsFif3yLJpg==",
    "type": "keyreg",
    "votefst": 1300,
    "votekd": 100,
    "votekey:b64": "UU8zLMrFVfZPnzbnL6ThAArXFsznV3TvFVAun2ONcEI=",
    "votelst": 11300
  }
}

Results in:

algorand://7IBEAXHK62XEJATU6Q4QYQCDFY475CEKNXGLYQO6QSGCLVMMK4SLVTYLMY?

type=keyreg

&selkey=-lfw-Y04lTnllJfncgMjXuAePe8i8YyVeoR9c1Xi78c

&sprfkey=3NoXc2sEWlvQZ7XIrwVJjgjM30ndhvwGgcqwKugk1u5W_iy_JITXrykuy0hUvAxbVv0njOgBPtGFsFif3yLJpg

&votefst=1300

&votekd=100

&votekey=UU8zLMrFVfZPnzbnL6ThAArXFsznV3TvFVAun2ONcEI

&votelst=11300

Encoding keyreg offline transaction:

{
  "txn": {
    "fee": 1000,
    "fv": 1776240,
    "gh:b64": "kUt08LxeVAAGHnh4JoAoAMM9ql/hBwSoiFtlnKNeOxA=",
    "lv": 1777240,
    "snd:b64": "+gJAXOr2rkSCdPQ5DEBDLjn+iIptzLxB3oSMJdWMVyQ=",
    "type": "keyreg"
  }
}

Results in:

algorand://7IBEAXHK62XEJATU6Q4QYQCDFY475CEKNXGLYQO6QSGCLVMMK4SLVTYLMY?type=keyreg

Encoding keyreg online transaction with custom fee and note:

{
  "txn": {
    "fee": 2000000,
    "fv": 1345,
    "gh:b64": "kUt08LxeVAAGHnh4JoAoAMM9ql/hBwSoiFtlnKNeOxA=",
    "lv": 2345,
    "note:b64": "Q29uc2Vuc3VzIHBhcnRpY2lwYXRpb24gZnR3",
    "selkey:b64": "+lfw+Y04lTnllJfncgMjXuAePe8i8YyVeoR9c1Xi78c=",
    "snd:b64": "+gJAXOr2rkSCdPQ5DEBDLjn+iIptzLxB3oSMJdWMVyQ=",
    "sprfkey:b64": "3NoXc2sEWlvQZ7XIrwVJjgjM30ndhvwGgcqwKugk1u5W/iy/JITXrykuy0hUvAxbVv0njOgBPtGFsFif3yLJpg==",
    "type": "keyreg",
    "votefst": 1300,
    "votekd": 100,
    "votekey:b64": "UU8zLMrFVfZPnzbnL6ThAArXFsznV3TvFVAun2ONcEI=",
    "votelst": 11300
  }
}

Results in:

algorand://7IBEAXHK62XEJATU6Q4QYQCDFY475CEKNXGLYQO6QSGCLVMMK4SLVTYLMY?

type=keyreg

&selkey=-lfw-Y04lTnllJfncgMjXuAePe8i8YyVeoR9c1Xi78c

&sprfkey=3NoXc2sEWlvQZ7XIrwVJjgjM30ndhvwGgcqwKugk1u5W_iy_JITXrykuy0hUvAxbVv0njOgBPtGFsFif3yLJpg

&votefst=1300

&votekd=100

&votekey=UU8zLMrFVfZPnzbnL6ThAArXFsznV3TvFVAun2ONcEI

&votelst=11300

&fee=2000000

&note=Consensus%2Bparticipation%2Bftw

Application NoOp Call URIs

NoOp calls are generic application calls that execute an Algorand smart contract’s approval program. This URI extension encodes the transactions so wallets, dApps, and services can invoke specific application methods using deeplinks and QR codes while remaining consistent with ARC-26. As with other URI types, the optional authority selects the network.

The ABNF overview defines noopurn, noopparams, and noopparam, which extend the shared productions with the application call keys described below.

As in ARC-26, URIs follow the general format for URIs as set forth in RFC 3986. The path component consists of an Algorand address, and the query component provides additional transaction parameters.

Elements of the query component may contain characters outside the valid range. These are encoded differently depending on their expected character set. The text components (note, xnote) 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. The binary components (args, refs, etc.) MUST be encoded with base64url as specified in RFC 4648 section 5.

Query Keys

Template URI vs Actionable URI

If the URI is constructed so that other dApps, wallets or protocols could use it with their runtime Algorand entities of interest, then the placeholder account/app address in the URI MUST be ZeroAddress (“AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ”). Since ZeroAddress cannot initiate any action this approach is considered non-vulnerable and secure.

Examples

Call claim(uint64,uint64)byte[] on contract 11111111 paying a fee of 10000 microAlgos from a specific address:

algorand://TMTAD6N22HCS2LKH7677L2KFLT3PAQWY6M4JFQFXQS32ECBFC23F57RYX4?type=appl&app=11111111&method=claim(uint64,uint64)byte[]&arg=20000&arg=474567&asset=45&fee=10000

Call the same method paying the default 1000 microAlgo fee while providing additional foreign applications:

algorand://TMTAD6N22HCS2LKH7677L2KFLT3PAQWY6M4JFQFXQS32ECBFC23F57RYX4?type=appl&app=11111111&method=claim(uint64,uint64)byte[]&arg=20000&arg=474567&asset=45&app=22222222&app=33333333

Blockchain Query URIs

This read-only URI extension defines a standardized method for querying application and asset data on Algorand. It enables applications, websites, and QR code implementations to construct URIs that retrieve application state, box data, and asset metadata in a structured format. The design is inspired by ARC-26 and reuses its core URI principles for consistency.

Algorand URIs in this section follow the general format for URIs as defined in RFC 3986. The authority optionally selects the network (gh:<hash> or net:<alias>), while the leading path segment specifies whether the URI targets an application (.../app/<id>) or an asset (.../asset/<id>). Query parameters define the specific data fields being requested. Parameters MAY contain characters outside the valid range. These MUST first be encoded in UTF-8, then percent-encoded according to RFC 3986.

The ABNF overview defines appqueryurn, appqueryparam, assetqueryurn, and assetqueryparam, which extend the shared productions with the query keys summarized below.

Application Query URIs (algorand://app)

The application URI allows querying the state of an application, including data from the application’s box storage, global storage, and local storage, as well as the TEAL program associated with it. Each storage type has specific requirements.

Asset Query URIs (algorand://asset)

The asset URI enables retrieval of metadata and configuration details for a specific asset, such as its name, total supply, decimal precision, and associated addresses.

Parameter Definitions

Application parameters

Asset parameters

Query Key Descriptions

For each parameter, the query key name is listed, followed by its purpose:

Examples

Query an application’s box storage:

algorand://app/2345?box=YWxnb3JvbmQ=

Query global storage:

algorand://app/12345?global=Z2xvYmFsX2tleQ==

Query local storage for a specific address:

algorand://app/12345?local=bG9jYWxfa2V5&algorandaddress=ABCDEFGHIJKLMNOPQRSTUVWXYZ234567

Query the total supply of an asset:

algorand://asset/67890?total

Rationale

The present aims to provide a standardized way to encode key registration transactions in order to enhance the user experience of signing key registration transactions in general, and in particular in the use case of an Algorand node runner that does not have their spending keys resident on their node (as is best practice). The parameter names were chosen to match the corresponding names in encoded key registration transactions.

Algorand application NoOp method calls cover the majority of application transactions in Algorand and have a wide range of use-cases. For use-cases where the runtime knows exactly what the called application needs in terms of arguments and transaction arrays and there are no direct interactions, this extension is required since the original ARC-26 standard did not support application calls.

Previously, the Algorand URI scheme was primarily used to create transactions on the chain. Extending it to cover read-only queries allows a URI scheme to directly retrieve information from the chain, specifically for applications and assets. This provides a unified, standardized method for querying Algorand application and asset data, allowing interoperability across applications and services.

Backwards Compatibility

This ARC replaces ARCs 26, 78, 79, and 82 without invalidating previously generated URIs. Existing URIs that conform to the earlier specifications remain valid under this consolidated definition, so no backwards incompatibilities are introduced beyond the deprecation of the superseded documents. For network selection, implementations MAY continue to accept the legacy query-based selectors during a migration period but SHOULD emit the authority-based form specified above.

Reference Implementation

None.

Security Considerations

The transaction-related sections of this specification introduce no additional security considerations beyond those identified in the originating ARCs.

Since the blockchain query URIs are intended for read-only operations, they do not alter application or asset state, mitigating many security risks. However, data retrieved from these URIs should be validated to ensure it meets user expectations and that any displayed data cannot be tampered with.

Copyright

Copyright and related rights waived via CCO.