Slot reference

Every slot in Magic Cloud and Hyperlambda, 406 in total, with its arguments and return value. Start with the core keywords, such as [if] and [for-each], or pick a namespace. Every slot has a page of its own, with its complete JSON declaration. How this reference is built is explained further down.

Slots by namespace

This reference was not written. It was asked for.

Every page in this section is generated, and what it is generated from is not the source code but the running system. Each slot in Magic Cloud carries its own name, description, arguments and return value as metadata, and Hyperlambda can read that metadata at runtime. Once a week a GitHub Actions workflow asks for it, receives 406 slots, and renders the pages you are reading. Nobody parses source files, scrapes anything or keeps a second copy that can go stale.

Why this is possible: homoiconicity

Hyperlambda is homoiconic. A program is a tree of nodes, and a tree of nodes is also the data structure the program works on. A slot is an ordinary node, and asking about slots is an ordinary function call: [vocabulary] lists their names, [slot.description] returns what one of them does, [slot.signature] returns its contract as a tree, and [lambda2hyper] writes any tree back as Hyperlambda text. Meta programming is not a library you import here, it is what the language does by default. This documentation is a Hyperlambda program whose input is the definition of Hyperlambda itself.

The code that produced this reference

This is the complete Hyperlambda file behind the endpoint the pipeline calls. This is dogfooding in its purest form: the language documents itself with its own code.

// Executable Hyperlambda file that lists every slot registered in the system and, for each slot, returns its name, its description and its signature. Returns a JSON array of objects, each with fields name (string), description (string) and signature (the slot's signature as nodes, so it converts to nested JSON). Open to everybody, since it only reads metadata that is public in the open source code and runs no code supplied by the caller. Callers are throttled to 10 requests per 60 seconds per IP address, and everybody together to 60 requests per 60 seconds.
.arguments
execution.throttle.create:docs-slots.ip
   limit:int:10
   window:int:60
   per:ip
execution.throttle.create:docs-slots.global
   limit:int:60
   window:int:60
   per:global
execution.throttle:docs-slots.ip
execution.throttle:docs-slots.global
vocabulary
.result
for-each:x:@vocabulary/*
   slot.description:x:@.dp/#
   slot.signature:x:@.dp/#
   /*
    * The signature is returned as nodes, which Magic converts to nested JSON. A constraint is
    * named after its kind and can occur more than once, which JSON cannot hold as a key, so each
    * constraint, at any depth, becomes an unnamed node carrying its kind as a child.
    */
   for-each:x:@slot.signature/**/constraints/*
      get-name:x:@.dp/#
      unwrap:x:+/*/*
      add:x:@.dp/#
         .
            kind:x:@get-name
      set-name:x:@.dp/#
         .:.
   .entry
      .
         name:x:@.dp/#
         description:x:@slot.description
         signature
   unwrap:x:@.entry/*/*
   add:x:@.entry/*/*/signature
      get-nodes:x:@slot.signature/*
   add:x:@.result
      get-nodes:x:@.entry/*
return-nodes:x:@.result/*

It begins with two throttles, one per IP address and one for everybody together, and has no authentication, since there is nothing to protect: it reads metadata that is public in the open source code and runs nothing a caller sends. Everything after that is slots, and nothing else. It lists the compiled slots, reads the description and the signature of each, and returns the signature as nodes. Magic turns nodes into JSON by itself, since a tree of nodes already is a tree of JSON objects, so there is no serialising step, no text format to agree on and nothing to parse. One detail shows how it works. A constraint is named after its kind and can occur more than once, which a JSON object cannot hold as a key, so the loop in the middle renames every constraint, at any depth, to an unnamed node with its kind as a child, using the ** selector to reach them all in one expression. Magic then writes them as a list. A Python script renders the result as markdown.

Get the whole reference yourself

The endpoint above is public. There is no account, no key and no secret. To protect the server it is throttled to 10 requests per 60 seconds per IP address, and to 60 per 60 seconds for everybody together, and beyond that it answers 429. The answer is about 460 KB, so keep a copy rather than asking again.

curl -s https://hyperlambda.dev/magic/modules/docs/slots

It returns a JSON array with one object per slot, with the fields name, description and signature. The signature is the contract of the slot as nested JSON: input is the value the slot takes, children are its arguments, constraints are the rules between them, scope says where it can be used, and output is what it returns. Arguments without a name, because they are positional, come as a list. With jq you can ask it questions.

List every slot name

curl -s https://hyperlambda.dev/magic/modules/docs/slots | jq -r '.[].name'

Get the description of one slot

curl -s https://hyperlambda.dev/magic/modules/docs/slots | jq -r '.[] | select(.name == "strings.concat") | .description'

Get the full signature of one slot

curl -s https://hyperlambda.dev/magic/modules/docs/slots | jq '.[] | select(.name == "data.read") | .signature'

List the arguments of a slot

curl -s https://hyperlambda.dev/magic/modules/docs/slots | jq -r '.[] | select(.name == "data.create") | .signature.children | keys[]'

List only the required arguments of a slot

curl -s https://hyperlambda.dev/magic/modules/docs/slots | jq -r '.[] | select(.name == "data.create") | .signature.children | to_entries[] | select(.value.required == true) | .key'

Find the slots whose description mentions something

curl -s https://hyperlambda.dev/magic/modules/docs/slots | jq -r '.[] | select((.description // "") | test("rows")) | .name'

The public sandbox below sees fewer slots than this endpoint. It runs your code, so it can only describe the 53 slots it is itself allowed to call. A slot can only be described by code that is allowed to call it, so a sandbox that described everything could also run everything. Use the endpoint for the whole language, and the sandbox to experiment.

The public sandbox

Anybody can send Hyperlambda to POST https://hyperlambda.dev/magic/modules/docs/playground, with no account and no key. It is rate limited to 30 requests per 60 seconds per IP address, stops after 20 seconds, and accepts up to 4000 characters. Every slot your code uses is checked against the whitelist before anything runs, so code that touches files, databases, the network or configuration is rejected rather than executed. Send {"describe": true} to get the exact vocabulary, limits and timeout without running anything. AI agents can find it in /.well-known/hyperlambda-agent, and it is yours to experiment with.

Save any example below as example.hl and send it like this.

jq -Rs '{hyperlambda: .}' example.hl | curl -s https://hyperlambda.dev/magic/modules/docs/playground \
  -H "Content-Type: application/json" -d @-

List the slot names

[vocabulary] returns the slots you are allowed to see. With a prefix it filters, so vocabulary:strings. returns only the string slots.

vocabulary:strings.
return-nodes:x:@vocabulary/*

Get one description

slot.description:strings.concat
return-value:x:@slot.description

Returns Concatenates strings.

Get every description

The same loop the full reference uses, without the signature.

vocabulary
.result
for-each:x:@vocabulary/*
   slot.description:x:@.dp/#
   .entry
      .
         name:x:@.dp/#
         description:x:@slot.description
   unwrap:x:@.entry/*/*
   add:x:@.result
      get-nodes:x:@.entry/*
return-nodes:x:@.result/*

Get one signature as Hyperlambda

[slot.signature] returns a tree, and [lambda2hyper] writes any tree back as Hyperlambda text. [lambda2json] would give you JSON instead.

slot.signature:convert
lambda2hyper:x:@slot.signature/*
return-value:x:@lambda2hyper

Get only the arguments of a slot

slot.signature:convert
.result
for-each:x:@slot.signature/*/children/*
   get-name:x:@.dp/#
   .entry
      .
         name:x:@get-name
         type:x:@.dp/#/*/type
         required:x:@.dp/#/*/required
         description:x:@.dp/#/*/description
   unwrap:x:@.entry/*/*
   add:x:@.result
      get-nodes:x:@.entry/*
return-nodes:x:@.result/*

Returns [{"name": "type", "type": "string", "required": true, "description": "Target Hyperlambda type name"}].

Get only the required arguments

slot.signature:convert
.result
for-each:x:@slot.signature/*/children/*
   if
      eq:x:@.dp/#/*/required
         .:bool:true
      .lambda
         get-name:x:@.dp/#
         unwrap:x:+/*/*
         add:x:@.result
            .
               .:x:@get-name
return-nodes:x:@.result/*

Returns ["type"].

This is the complete source of the sandbox endpoint, generated by the Sandbox API generator in Magic Cloud. The policy near the top is the whole whitelist.

Show the entire sandbox endpoint
/*
 * Sandboxed Hyperlambda endpoint, generated by the Sandbox API generator.
 *
 * Executes caller-supplied Hyperlambda passed in [hyperlambda].
 *
 * Roles:
 *
 * - *****: Can introspect every compiled slot of the system - its name, description and full signature - and transform the result with pure tree, string and math functions. Cannot touch files, databases, the network, configuration or any other part of the server.
 *
 * The code is checked - every referenced function must exist on this server - then
 * executed inside a whitelisted sandbox whose vocabulary and rate limit are chosen
 * from the caller's roles. Always returns the code together with a [state] describing
 * what happened, and a [reason] whenever the runtime refused the code or it failed.
 *
 * To discover the exact capability surface available to you, call with [describe] set
 * to true instead of [hyperlambda]/[instruction] - it returns your visible vocabulary,
 * and the rate limit and timeout that apply to you, without executing anything or
 * counting against the rate limit.
 *
 * States: described (a [describe] call), executed, rejected (a function or a pinned
 * argument was not allowed), unknown-slot (a referenced function does not exist),
 * invalid-invocation (a declared argument is misspelled or a mandatory value is absent),
 * error (the code threw), timeout (execution exceeded the configured limit),
 * generator-failed (no code came back from the Hyperlambda Generator).
 */
.arguments

   // Hyperlambda to execute as-is inside the sandbox, at most [max-hyperlambda] characters.
   hyperlambda:string

   // When true, returns your visible vocabulary instead of executing [instruction]/[hyperlambda].
   describe:bool

/*
 * Policy - injected by the generator. [rules] are matched top down: a rule matches
 * when its [role] is '*' or the caller belongs to it. The vocabulary is the union of
 * every matching rule's [slots]. The rate limit and the timeout are each taken from
 * the first matching rule that declares one, resolved independently, so a rule can
 * override one, both, or neither. Rules are ordered most-access-first, and the '*'
 * base rule sits last as the fallback for both.
 */
.policy
   override-root:bool:false
   return-code:bool:false
   generator-url:"https://ainiro.io/magic/modules/hyperlambda-generator/chat"
   throttle-prefix:sandbox-docs-playground-post
   max-hyperlambda:int:4000
   rules
      .
         role:*
         slots
            vocabulary
            slot.description
            slot.signature
            lambda2hyper
            hyper2lambda
            lambda2json
            json2lambda
            for-each
            if
            else
            else-if
            eq
            neq
            mt
            mte
            lt
            lte
            not
            and
            or
            exists
            not-exists
            null
            not-null
            add
            get-nodes
            get-value
            get-name
            set-value
            set-name
            remove-nodes
            unwrap
            sort
            convert
            return
            return-nodes
            return-value
            strings.concat
            strings.contains
            strings.starts-with
            strings.ends-with
            strings.to-lower
            strings.to-upper
            strings.join
            strings.split
            strings.replace
            strings.length
            strings.substring
            strings.trim
            math.add
            math.subtract
            math.multiply
            math.divide
         description:Can introspect every compiled slot of the system - its name, description and full signature - and transform the result with pure tree, string and math functions. Cannot touch files, databases, the network, configuration or any other part of the server.
         limit:int:30
         window:int:60
         timeout:int:20000

// Result fields.
.code
.state
.reason
.result
.execute:bool:false

// Resolving the caller's identity once, for the role checks below.
auth.ticket.get

// Whether the caller is root. Root is never rate limited, whatever the policy says.
.is-root:bool:false
if
   auth.ticket.in-role:root
   .lambda
      set-value:x:@.is-root
         .:bool:true

/*
 * Whether the caller bypasses the sandbox entirely, running the code with the
 * server's full vocabulary and no whitelist. Only when the policy enables it AND
 * the caller is root.
 */
.bypass:bool:false
if
   and
      get-value:x:@.policy/*/override-root
      get-value:x:@.is-root
   .lambda
      set-value:x:@.bypass
         .:bool:true

/*
 * Rate limit and timeout for sandboxed (non-root) callers - root has neither. Both are
 * resolved independently by walking the rules top down and taking the first matching rule
 * that declares that dimension, so an earlier rule can override one, both, or neither,
 * with the '*' base rule as the fallback. Resolved ahead of [describe] so that it can tell
 * the caller what it is subject to, and applied only once there is code to run.
 */
.tname
.tlimit:int:0
.twindow:int:0
.ttimeout
if
   not
      get-value:x:@.is-root
   .lambda

      // Rate limit - first matching rule that declares a [limit].
      for-each:x:@.policy/*/rules/*
         if
            and
               null:x:@.tname
               not-null:x:@.dp/#/*/limit
               or
                  eq:x:@.dp/#/*/role
                     .:*
                  auth.ticket.in-role:x:@.dp/#/*/role
            .lambda
               set-value:x:@.tname
                  strings.concat
                     get-value:x:@.policy/*/throttle-prefix
                     .:-
                     get-value:x:@.dp/#/*/role
               set-value:x:@.tlimit
                  get-value:x:@.dp/#/*/limit
               set-value:x:@.twindow
                  get-value:x:@.dp/#/*/window

      // Timeout - first matching rule that declares a [timeout].
      for-each:x:@.policy/*/rules/*
         if
            and
               null:x:@.ttimeout
               not-null:x:@.dp/#/*/timeout
               or
                  eq:x:@.dp/#/*/role
                     .:*
                  auth.ticket.in-role:x:@.dp/#/*/role
            .lambda
               set-value:x:@.ttimeout
                  get-value:x:@.dp/#/*/timeout

/*
 * A caller asking to [describe] the sandbox gets back its own visible vocabulary, and
 * the rate limit and timeout it is subject to, instead of executing anything. This runs
 * before [instruction]/[hyperlambda] are required, and before the rate limit is applied,
 * so discovering what is allowed here never costs the caller's execution budget.
 *
 * The vocabulary is a list with one object per slot, carrying its [name] and its pinned
 * [value] (null when unpinned). It cannot be a map keyed by slot name, since the same
 * slot can be whitelisted more than once with different pinned values.
 */
if
   get-value:x:@.arguments/*/describe
   .lambda
      .response
         state:described
         vocabulary

      /*
       * A bypassing caller (root, when the policy lets root skip the sandbox) runs with
       * the server's full vocabulary, so that is what it is told - never just the base.
       */
      if
         get-value:x:@.bypass
         .lambda
            vocabulary
            for-each:x:@vocabulary/*
               .row
                  .
                     name
                     value
               set-value:x:@.row/0/*/name
                  get-value:x:@.dp/#
               add:x:@.response/*/vocabulary
                  get-nodes:x:@.row/*
            add:x:@.response
               .
                  root-bypass:bool:true
      else

         // Everybody else gets the union of every matching rule's slots.
         .vocabulary
         for-each:x:@.policy/*/rules/*
            if
               or
                  eq:x:@.dp/#/*/role
                     .:*
                  auth.ticket.in-role:x:@.dp/#/*/role
               .lambda
                  add:x:@.vocabulary
                     get-nodes:x:@.dp/#/*/slots/*
         for-each:x:@.vocabulary/*
            .row
               .
                  name
                  value
            set-value:x:@.row/0/*/name
               get-name:x:@.dp/#
            set-value:x:@.row/0/*/value
               get-value:x:@.dp/#
            add:x:@.response/*/vocabulary
               get-nodes:x:@.row/*

      /*
       * What the caller is subject to: invocations per [window] seconds, per IP, and the
       * timeout in milliseconds. Either is left out when it does not apply, as for root.
       */
      if
         not-null:x:@.tname
         .lambda
            add:x:@.response
               .
                  limit
                  window
            set-value:x:@.response/*/limit
               get-value:x:@.tlimit
            set-value:x:@.response/*/window
               get-value:x:@.twindow
      if
         not-null:x:@.ttimeout
         .lambda
            add:x:@.response
               .
                  timeout
            set-value:x:@.response/*/timeout
               get-value:x:@.ttimeout
      return-nodes:x:@.response/*

/*
 * Applying the rate limit resolved above to sandboxed (non-root) callers. The throttle
 * is keyed by the caller's IP; declaring an unchanged throttle keeps its counters, so
 * the declaration can live in the endpoint itself.
 */
if
   not-null:x:@.tname
   .lambda
      execution.throttle.create:x:@.tname
         limit:x:@.tlimit
         window:x:@.twindow
         per:ip
      execution.throttle:x:@.tname

/*
 * Resolving the code to run. A non-empty [instruction] is natural language and is
 * sent to the Hyperlambda Generator; otherwise the raw [hyperlambda] is used.
 */
if
   and
      not-null:x:@.arguments/*/instruction
      neq:x:@.arguments/*/instruction
         .:
   .lambda
      validators.string:x:@.arguments/*/instruction
         min:int:3
         max:int:500
      http.post:x:@.policy/*/generator-url
         convert:bool:true
         timeout:int:60
         payload
            prompt:x:@.arguments/*/instruction
      if
         or
            lt:x:@http.post
               .:int:200
            mte:x:@http.post
               .:int:300
            null:x:@http.post/*/content/*/result
         .lambda
            return
               state:generator-failed
               code
               reason:The Hyperlambda Generator did not return any code.
               result
      set-value:x:@.code
         get-value:x:@http.post/*/content/*/result
else-if
   and
      not-null:x:@.arguments/*/hyperlambda
      neq:x:@.arguments/*/hyperlambda
         .:
   .lambda

      // Rejecting oversized code up front, before anything is parsed or executed.
      validators.string:x:@.arguments/*/hyperlambda
         max:x:@.policy/*/max-hyperlambda
      set-value:x:@.code
         get-value:x:@.arguments/*/hyperlambda
else
   throw:Provide either an instruction or Hyperlambda to execute
      status:int:400
      public:bool:true

/*
 * Static sanity check before running anything: every referenced function must exist
 * on this server, otherwise a hallucinated name would be treated as inert data.
 */
hyperlambda.verify-slots:x:@.code
if
   not
      get-value:x:@hyperlambda.verify-slots
   .lambda
      if
         exists:x:@hyperlambda.verify-slots/invalid-invocation
         .lambda
            set-value:x:@.state
               .:invalid-invocation
            set-value:x:@.reason
               strings.join:x:@hyperlambda.verify-slots/invalid-invocation
                  .:"; "
      else
         set-value:x:@.state
            .:unknown-slot
         set-value:x:@.reason
            strings.concat
               .:"The code references functions that do not exist on this server: "
               strings.join:x:@hyperlambda.verify-slots/*
                  .:", "
else
   set-value:x:@.execute
      .:bool:true

// Bypass callers (root, when the policy allows it) run with full trust, no sandbox.
if
   and
      eq:x:@.execute
         .:bool:true
      eq:x:@.bypass
         .:bool:true
   .lambda

      // No timeout - root is fully trusted with the server.
      try
         hyper2lambda:x:@.code
         invoke:x:@hyper2lambda
         set-value:x:@.state
            .:executed
         if
            not-null:x:@invoke
            .lambda
               set-value:x:@.result
                  get-value:x:@invoke
         else
            add:x:@.result
               get-nodes:x:@invoke/*
      .catch
         if
            strings.contains:x:@.arguments/*/message
               .:cancel
            .lambda
               set-value:x:@.state
                  .:timeout
         else
            set-value:x:@.state
               .:error
         set-value:x:@.reason
            get-value:x:@.arguments/*/message

// Sandboxed callers run inside a whitelist whose vocabulary is chosen from their roles.
else-if
   eq:x:@.execute
      .:bool:true
   .lambda
      try

         // Timeout resolved above; null for root, which is fully trusted with the server.
         if
            not-null:x:@.ttimeout
            .lambda
               execution.timeout:x:@.ttimeout

         // Assembling the vocabulary as the union of every matching rule's slots.
         .vocabulary
         for-each:x:@.policy/*/rules/*
            if
               or
                  eq:x:@.dp/#/*/role
                     .:*
                  auth.ticket.in-role:x:@.dp/#/*/role
               .lambda
                  add:x:@.vocabulary
                     get-nodes:x:@.dp/#/*/slots/*

         // Parsing the code and populating the whitelist's body and vocabulary.
         hyper2lambda:x:@.code
         add:x:./*/whitelist/*/.lambda
            get-nodes:x:@hyper2lambda/*
         add:x:./*/whitelist/*/vocabulary
            get-nodes:x:@.vocabulary/*
         whitelist
            vocabulary
            .lambda
         set-value:x:@.state
            .:executed
         if
            not-null:x:@whitelist
            .lambda
               set-value:x:@.result
                  get-value:x:@whitelist
         else
            add:x:@.result
               get-nodes:x:@whitelist/*
      .catch
         if
            strings.contains:x:@.arguments/*/message
               .:not allowed
            .lambda
               set-value:x:@.state
                  .:rejected
         else-if
            strings.contains:x:@.arguments/*/message
               .:cancel
            .lambda
               set-value:x:@.state
                  .:timeout
         else
            set-value:x:@.state
               .:error
         set-value:x:@.reason
            get-value:x:@.arguments/*/message

/*
 * Returning the verdict and result to the caller, in order: [state], then [code] only
 * when the policy asks for it, then [reason] only when there is one to explain, then
 * [result] last.
 */
.response
   state
set-value:x:@.response/*/state
   get-value:x:@.state

// [code] - only when the policy enables returning it.
if
   get-value:x:@.policy/*/return-code
   .lambda
      add:x:@.response
         .
            code
      set-value:x:@.response/*/code
         get-value:x:@.code

// [reason] - only when there is one; a clean run has nothing to explain.
if
   not-null:x:@.reason
   .lambda
      add:x:@.response
         .
            reason
      set-value:x:@.response/*/reason
         get-value:x:@.reason

// [result] - last, and always present.
add:x:@.response
   .
      result
if
   exists:x:@.result/*
   .lambda
      add:x:@.response/*/result
         get-nodes:x:@.result/*
else
   set-value:x:@.response/*/result
      get-value:x:@.result
return-nodes:x:@.response/*

The pipeline

This is the complete GitHub Actions workflow. It needs no credentials, since the endpoint is public.

Show the entire workflow
# Keeps the plugin pages and the generated slot reference in sync with Magic Cloud.
#
# Two jobs in one run:
#
# * sync-plugin-docs.py copies each plugin's README.md from the Magic repository,
#   https://github.com/polterguy/magic, to plugins/<plugin>/index.md, adapted for Jekyll.
#   The README is the source of truth.
# * build-slot-reference.py asks a read-only Hyperlambda endpoint on hyperlambda.dev for
#   every compiled slot and renders reference/slots/ from the answer. The endpoint is
#   public and throttled, so no credentials are needed. Nothing is built, and no source
#   code is parsed.
#
# It runs weekly and on demand, since the Magic repository is a separate project that
# cannot trigger this one without a token. Run it from the Actions tab after a release.
# The commit touches nothing outside plugins/ and reference/, and llms-full.yml rebuilds
# llms-full.txt afterwards because markdown changed.

name: Sync plugin docs and slot reference

on:
  schedule:
    - cron: '0 5 * * 1'
  workflow_dispatch:

permissions:
  contents: write

concurrency:
  group: slot-reference
  cancel-in-progress: true

jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/checkout@v4
        with:
          repository: polterguy/magic
          path: magic

      - uses: actions/setup-python@v5
        with:
          python-version: '3.x'

      - name: Copy plugin READMEs
        run: python3 .github/scripts/sync-plugin-docs.py magic

      # Fails, and writes nothing, when the endpoint answers with too few slots.
      - name: Generate slot reference
        run: python3 .github/scripts/build-slot-reference.py

      # Only commit when something actually changed.
      - name: Commit if changed
        run: |
          git add plugins reference
          if git diff --cached --quiet; then
            echo "Nothing changed."
            exit 0
          fi
          git config user.name  "github-actions[bot]"
          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
          git commit -m "Sync plugin docs and slot reference"
          git push

Frequently asked questions

How is this slot reference generated?

Automatically, from the running system. A GitHub Actions workflow asks a Hyperlambda endpoint on hyperlambda.dev for every compiled slot. The endpoint runs a short Hyperlambda program that lists the slots with [vocabulary] and reads each slot's description and signature with [slot.description] and [slot.signature]. A Python script renders the answer as the pages in this section.

Why is it generated instead of written by hand?

A slot describes itself in the same place its code lives, so the reference cannot drift away from the implementation. If an entry is thin or wrong, the fix is to improve the slot's own metadata, and the next run publishes it.

What is homoiconicity?

A language is homoiconic when its programs are stored in a data structure the language itself can read and change. In Hyperlambda a program is a tree of nodes, and so is the metadata that describes every slot, so a program can ask the system about itself and process the answer with the same tools it uses for any other data.

What is meta programming, and where is it here?

Meta programming is code that reads, generates or transforms code. This reference is a Hyperlambda program whose input is the definition of Hyperlambda itself: it lists the language's own slots, reads their contracts, and the result becomes the documentation.

Can I run my own Hyperlambda against the public sandbox?

Yes. POST your code as JSON to https://hyperlambda.dev/magic/modules/docs/playground, with no account or key. It is rate limited to 30 requests per 60 seconds per IP address, runs for at most 20 seconds, and accepts at most 4000 characters of code.

Is it safe to let anybody run code on that server?

The sandbox only runs code whose every slot is on a whitelist of 53 slots: introspection, tree handling, strings and arithmetic. Code that touches files, databases, the network, configuration or anything else is rejected before it runs, and every call is rate limited and time limited.

Can I get the whole reference as data?

Yes. GET https://hyperlambda.dev/magic/modules/docs/slots returns every compiled slot as a JSON array of objects with the fields name, description and signature, where the signature is the slot's contract as nested JSON. It needs no account or key. The answer is about 460 KB, so keep a copy rather than asking again.

Is it safe to leave that endpoint open?

It only reads metadata that is already public in the open source code, and it runs nothing that the caller sends. It is throttled to 10 requests per 60 seconds per IP address and 60 per 60 seconds for everybody together, and answers 429 beyond that.

Why does the sandbox show fewer slots than this reference?

The sandbox runs your code, so it can only describe the 53 slots it is itself allowed to call. A slot can only be described by code that is allowed to call it, so a sandbox that described everything could also run everything. Use the slot endpoint for the whole language and the sandbox to experiment.

How do I get only the descriptions, or only the arguments, of some slots?

Use [vocabulary] with a prefix to pick slots by name, [slot.description] for one description, and [slot.signature] for the input, arguments and output of one slot. The examples on this page show each of them, and all of them run in the public sandbox.

Does every slot have its own page?

Yes. Each slot has a page of its own, at /reference/slots/ followed by its namespace and its name, for example /reference/slots/strings/strings.concat/. It is small enough to read or index on its own, with its value, arguments, constraints, return value and complete JSON declaration. The namespace pages are indexes that link to them.

Where do I find the JSON declaration of a single slot?

At the bottom of the slot's page, in an expandable section with a copy button, and as a file next to the page called slot.json. For strings.concat that is /reference/slots/strings/strings.concat/slot.json.

How do I fix a missing or wrong description?

Change the metadata on the slot in the source code of Magic Cloud, its description or its signature. The next run of the pipeline publishes it here.

How often is the reference updated?

Once a week, and on demand from the Actions tab of the documentation repository.

What is Hyperlambda?

Hyperlambda is a declarative programming language where the source code is a tree of nodes rather than free-form text. It runs on Magic Cloud, an open source, MIT licensed platform that builds and runs an entire backend.

Is Hyperlambda Turing complete?

Yes. Slots such as [if], [for-each] and [while] give it branching and loops, which is what makes it Turing complete.

Why do I get error code 1010 when I call the endpoint from a script?

The server sits behind Cloudflare, which rejects requests that carry no User-Agent header, or the default one of an http library such as Python's urllib. Send any descriptive User-Agent and the request goes through.