Decode an AIPM 1.0 URL

Paste any AIPM 1.0 URL to decode it. AIPM 1.0 used query parameters (not hash fragments) — e.g. https://aipmq.org/1.0/aipm/?v=1.0&role=prompted&... 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.0 decode page

Paste AIPM URL

AIPM 1.0 — Original release. Metadata is encoded in query strings (?v=1.0&role=…), not hash fragments. Parameters: v, role, model, date, ctx.

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.0 URL decoder — stdlib only, no external dependencies.
Specification: https://aipmq.org/1.0/spec/

Usage:
  python3 aipm_decode.py 'https://aipmq.org/1.0/aipm/?v=1.0&role=prompted&...'
  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."""
    parsed = urlparse(url.strip())
    fragment = parsed.query  # AIPM 1.0 used query params, not hash fragments
    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 1.0 URL encodes its metadata in the query string — the part after ?. The query string is visible in the URL itself.

Plain URL (no compression)

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

vAIPM version (e.g. 1.2)
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)

AIPM 1.0 does not use compression — all metadata is plain query string parameters. 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.