Decode an AIPM 1.1 URL

Paste any AIPM 1.1 URL to decode it without visiting the display page. Useful when the primary site is unavailable, for archival verification, or when you prefer a local decode.

Archived copy of this page: web.archive.org — AIPM 1.1 decode page

Paste AIPM URL

AIPM 1.1 — stable release. Metadata is encoded in hash fragments (#v=1.1&role=…). All fields are human-readable plain text. Parameters include v, role, model, ctx, date, show, src, doc, author, org, prev, and lang.

Decoder options

Copy this script and run it with any Python 3.x installation. No external dependencies — standard library only. This is the most durable decode method.

#!/usr/bin/env python3
"""
AIPM 1.1 URL decoder — stdlib only, no external dependencies.
Specification: https://aipmq.org/1.1/spec/

Usage:
  python3 aipm_decode.py 'https://aipmq.org/1.1/aipm/#v=1.1&...'
  python3 aipm_decode.py        # paste URL when prompted
"""
import sys, json, zlib, base64
from urllib.parse import urlparse, parse_qs


FIELD_LABELS = {
    'v':      'AIPM version',
    'role':   'Human role',
    'model':  'AI model',
    'ctx':    'Context / prompt',
    'date':   'Date',
    'show':   'Show mode',
    'src':    'Content URL',
    'hs':     'Content hash (SHA)',
    'type':   'Content type',
    'doc':    'Full Context Document URL',
    'hd':     'Document hash (SHA)',
    'author': 'Author',
    'org':    'Organisation',
    'lang':   'Language',
    'prev':   'Previous mark URL',
    'qr':     'QR only (qr=0 = URL only)',
}


def decode_aipm_url(url: str) -> dict:
    """Parse an AIPM URL and return its metadata fields."""
    fragment = urlparse(url.strip()).fragment
    if not fragment:
        raise ValueError("No hash fragment found in URL. "
                         "AIPM metadata lives after the '#' character.")

    params = parse_qs(fragment, keep_blank_values=True)
    get = lambda k: params.get(k, [None])[0]

    z = get('z')
    if z:
        # Decompress deflate-raw + base64url payload (AIPM 1.1+)
        b64 = z.replace('-', '+').replace('_', '/')
        b64 += '=' * (-len(b64) % 4)   # restore base64 padding
        raw = base64.b64decode(b64)
        # wbits=-15 → raw DEFLATE (RFC 1951), no zlib/gzip wrapper
        return json.loads(zlib.decompress(raw, wbits=-15))
    else:
        # Plain params (human-readable, no compression)
        fields = ['v', 'role', 'model', 'ctx', 'date', 'show',
                  'src', 'hs', 'type', 'doc', 'hd',
                  'author', 'org', 'lang', 'prev', 'qr']
        return {k: get(k) for k in fields if get(k) is not None}


def main():
    if len(sys.argv) > 1:
        url = ' '.join(sys.argv[1:])
    else:
        url = input('Paste AIPM URL: ').strip()

    data = decode_aipm_url(url)
    print()
    max_label = max((len(FIELD_LABELS.get(k, k)) for k in data), default=10)
    for k, v in data.items():
        label = FIELD_LABELS.get(k, k)
        print(f'  {label:<{max_label}} : {v}')
    print()


if __name__ == '__main__':
    main()

An AIPM URL encodes its metadata in the hash fragment — the part after #. The fragment never reaches the server, so all metadata is visible in the URL itself.

Plain URL (no compression)

If the URL contains readable parameters after #, decode each key=value pair:

vAIPM version (must be 1.1)
roleHuman role: all, wrote, prompted+reviewed, prompted+edited, prompted, edited, reviewed, supervised, automated
modelAI model or system name
ctxContext / prompt description (URL-decoded)
dateISO 8601 date or datetime
show1 = show role abbreviation on QR mark
srcLink to the content this mark applies to
hsSHA hash of the content file — W3C SRI format (sha256-… or sha384-…)
typeContent type: text, code, image, audio, video, multimodal
docLink to the Full Context Document
hdSHA hash of the Full Context Document — W3C SRI format
authorHuman creator name
orgOrganisation
langBCP 47 language tag (e.g. en, fr)
prevURL of previous AIPM mark — creates a provenance chain
qr0 = URL-only mode (no QR possible — payload too large)

Compressed URL (z= parameter)

If the URL fragment starts with z=, the metadata is compressed. The z value is a raw DEFLATE (RFC 1951, no zlib wrapper) compressed JSON object, encoded in base64url (no padding).

To decode in a terminal (Python 3 standard library):

python3 -c "
import sys, json, zlib, base64
z = input('Paste z= value: ')
b64 = z.replace('-','+').replace('_','/')
b64 += '=' * (-len(b64) % 4)
raw = base64.b64decode(b64)
print(json.dumps(json.loads(zlib.decompress(raw, wbits=-15)), indent=2))
"

The resulting JSON contains the same field names as the plain-URL table above.

⚠ Experimental. This option runs Python in your browser via Pyodide/WebAssembly. It requires downloading ~10MB and may not work in all browsers or future browser versions. The Python snippet tab is more reliable for long-term use.

Paste your AIPM URL in the box above, then click the button below. Pyodide will load on first use (~10MB download).

If aipmq.org becomes unavailable, these archived copies of this decode page can be used instead:

The Python snippet on the previous tab works entirely offline and requires no network access. It is the most resilient long-term option. Keep a local copy of the script if you need guaranteed offline decode capability.

The Python snippet tab gives you a fully offline, domain-independent decoder you can save and run anywhere — no network, no browser, no dependencies beyond Python 3.6's standard library.